एकल पृष्ठ एप्लिकेशन में AngularJS के साथ कई नियंत्रक


102

मैं जानना चाहता हूं कि किसी एकल पृष्ठ अनुप्रयोग के लिए कई नियंत्रकों का उपयोग कैसे किया जाता है। मैंने इसका पता लगाने की कोशिश की है और मुझे मेरे जैसे ही सवाल मिले हैं, लेकिन एक विशिष्ट समस्या को हल करने के लिए सिर्फ एक टन है, जहां आप एक पेज ऐप के लिए कई नियंत्रकों का उपयोग नहीं करते हैं।

क्या इसलिए कि एक ही पृष्ठ के लिए कई नियंत्रकों का उपयोग करना बुद्धिमानी नहीं होगी? या यह सिर्फ संभव नहीं है?

मान लें कि मेरे पास पहले से ही एक किक-गधा छवि हिंडोला नियंत्रक है जो मुख्य पृष्ठ पर काम कर रहा है, लेकिन फिर मैं सीखता हूं कि कैसे (चलो कहते हैं) मोडल्स का उपयोग करें और मुझे इसके लिए एक नया नियंत्रक चाहिए (या किसी अन्य चीज के लिए मुझे एक नियंत्रक की आवश्यकता है)। फिर क्या करूंगा?

मैंने अन्य प्रश्नों के कुछ उत्तर देखे हैं जहाँ वे मुझसे लगभग एक ही तरह की चीज़ों के बारे में पूछते हैं और लोग "ओएमजी" का उत्तर देते हैं। आप भी ऐसा क्यों करेंगे, बस यही करें ... "।

सबसे अच्छा तरीका क्या है, या आप इसे कैसे करते हैं?

संपादित करें

आप में से कई लोग दो नियंत्रक घोषित करने का जवाब दे रहे हैं और फिर इसे कॉल करने के लिए एनजी-नियंत्रक का उपयोग करें। मैं नीचे दिए गए कोड के इस बिट का उपयोग करता हूं और फिर Main -trl को एनजी कंट्रोलर के साथ कॉल करता हूं।

app.config(function($routeProvider, $locationProvider) {                        
  $routeProvider                                                                
       .when('/', {                                            
         templateUrl: "templates/main.html",                                               
         controller:'MainCtrl',                                
        })                                                                      
        .otherwise({                      
            template: 'does not exists'   
        });      
});

यहां तक ​​कि मुझे यहां एक नियंत्रक सेट करने की आवश्यकता क्यों है अगर मैं इसके बिना सिर्फ एनजी-नियंत्रक का उपयोग कर सकता हूं? यही मुझे भ्रमित करता है। (और आप इस तरह से दो कंट्रोलर नहीं जोड़ सकते, मुझे लगता है ...)


मुझे नहीं लगता कि मैं एक .html फ़ाइल के लिए 2 नियंत्रक घोषित कर सकता हूँ? यह कैसे किया जाता है when: /home, controller: MainCtrl। उस से अधिक नहीं जोड़ सकते हैं, या डु आप मतलब है कि यह सिर्फ एनजी नियंत्रक के साथ कहते हैं?

3
@Mosho, आपने चरण 1, चरण 2, किया, लेकिन समझा नहीं कि कैसे या क्यों। अगर यह इतना आसान है, तो कृपया कैसे समझाएं। यह कहना है कि AngularJS, Done का उपयोग करें। क्या आप विस्तृत / व्याख्या कर सकते हैं? या इसके जून से, वे जवाब नहीं दे सकते हैं, क्या कोई और समझा सकता है?
redfox05

जवाबों:


96

समस्या क्या है? कई नियंत्रकों का उपयोग करने के लिए, बस कई एनको कंट्रोलर निर्देशों का उपयोग करें:

<div class="widget" ng-controller="widgetController">
    <p>Stuff here</p>
</div>

<div class="menu" ng-controller="menuController">
    <p>Other stuff here</p>
</div>

आपको अपने एप्लिकेशन मॉड्यूल में हमेशा की तरह नियंत्रक उपलब्ध होना चाहिए।

इसे करने का सबसे मूल तरीका इस तरह के नियंत्रक कार्यों की घोषणा करना जितना आसान हो सकता है:

function widgetController($scope) {
   // stuff here
}

function menuController($scope) {
   // stuff here
}

2
क्या यह कैसे किया जाता है? Im का उपयोग कर किwhen /home, controller: MainCtrl

8
यदि आप अपने "एनजी-नियंत्रक" के बगल में प्रत्येक डीआईवी में "एनजी-ऐप" डालते हैं तो ऐसे उदाहरण आ रहे हैं, "बॉडी" टैग में केवल एक "एनजी-ऐप" को स्थानांतरित करने का प्रयास करें (और प्रति-डीव हटाएं) एनजी-ऐप "टैग) यदि केवल आपका पहला नियंत्रक काम करता है। (मुझे यह मेरे कोणीय
नवाबी

1
एकमात्र मुद्दा जो मैंने ng-controllerकई DOM तत्वों में उपयोग करने के साथ लिया है , एक परिदृश्य में कहता है कि मेरे पास DOM के माध्यम से MANY आइटम कहां हैं ng-repeat। मान लीजिए कि इनमें से प्रत्येक कॉल करता है ng-controller="myController। कुछ सांत्वना लॉग में से मैंने अपने आवेदन में देखा है, myControllerEACH तत्व के साथ फिर से इनिशियलाइज़ किया जा रहा है DOM में जो इसे कॉल करता है .... शायद मैंने अपने विशेष उपयोग में कुछ खराब कर दिया है, या शायद OP के दायरे से परे सवाल है, लेकिन उत्सुक अगर दूसरों का अनुभव किया है कि सभी ....
twknab

91

मुझे लगता है कि आप "सिंगल पेज ऐप" को याद कर रहे हैं।

इसका मतलब यह नहीं है कि आपके पास भौतिक रूप से एक .html होगा, इसके बजाय आपके पास एक मुख्य index.htmlऔर कई NESTED .html फ़ाइल होगी। तो सिंगल पेज ऐप क्यों? क्योंकि इस तरह से आप पृष्ठों को मानक तरीके से लोड नहीं करते हैं (यानी ब्राउज़र कॉल जो पूर्ण पृष्ठ को पूरी तरह से ताज़ा करता है) लेकिन आप सिर्फ अंगुलर / अजाक्स का उपयोग करके सामग्री भाग को लोड करते हैं। चूंकि आपको पृष्ठ परिवर्तनों के बीच झिलमिलाहट दिखाई नहीं देती है, इसलिए आपको आभास होता है कि आप पृष्ठ से नहीं हटे हैं। इस प्रकार, आप ऐसा महसूस करते हैं कि आप किसी एक पृष्ठ पर रह रहे हैं।

अब, मैं मान रहा हूँ कि आप अपने SINGLE PAGE ऐप के लिए MULTIPLE सामग्री रखना चाहते हैं: (जैसे) घर, संपर्क, पोर्टफोलियो और स्टोर। आपका एकल पृष्ठ / एकाधिक सामग्री ऐप (कोणीय तरीका) इस तरह से व्यवस्थित किया जाएगा:

  • index.html: इसमें शीर्षलेख <ng-view>और पाद लेख शामिल हैं
  • contacts.html: संपर्क फ़ॉर्म (कोई हेडर, कोई पाद नहीं) होता है
  • portfolio.html: पोर्टफोलियो डेटा (कोई हेडर नहीं पाद लेख) होता है
  • store.html: इसमें स्टोर होता है, कोई हेडर नहीं फुटर होता है।

आप सूचकांक में हैं, आप "संपर्क" नामक मेनू पर क्लिक करते हैं और क्या होता है? कोणीय कोड के <ng-view>साथ टैग को बदलता हैcontacts.html

आप इसे कैसे प्राप्त करेंगे? साथ ngRoute, के रूप में आप कर रहे हैं, तो आप की तरह कुछ करना होगा:

app.config(function($routeProvider, $locationProvider) {                        
  $routeProvider                                                                
       .when('/', {                                            
         templateUrl: "templates/index.html",                                               
         controller:'MainCtrl',                                
        })
        .when('/contacts', {                                            
         templateUrl: "templates/contacts.html",                                               
         controller:'ContactsCtrl',                                
        })                                                                 
        .otherwise({                      
            template: 'does not exists'   
        });      
});

यह सही html को सही नियंत्रक से गुजरता हुआ कहेगा (कृपया ध्यान दें: यदि आप मार्गों का उपयोग कर रहे हैं तो निर्देश निर्दिष्ट न करेंng-controllercontacts.html )

फिर, निश्चित रूप से, आप अपने contacts.html पेज के अंदर कई एनजी-नियंत्रक निर्देशों की घोषणा कर सकते हैं। वे ContactCtrl(जैसे इस से विरासत में) के बाल नियंत्रक होंगे । लेकिन एक मार्ग के लिए, अंदर routeProvider, आप एक एकल नियंत्रक की घोषणा कर सकते हैं जो "आंशिक दृश्य के पिता नियंत्रक" के रूप में कार्य करेगा।

संपादित करें निम्नलिखित टेम्पलेट्स / contacts.html की कल्पना करें

<div>
    <h3>Contacts</h3>
    <p>This is contacts page...</p>
</div>

उपरोक्त routeProviderआपके div में एक नियंत्रक इंजेक्ट करेगा। मूल रूप से ऊपर HTML स्वचालितता बन जाती है:

<div ng-controller="ContactsCtrl">
    <h3>Contacts</h3>
    <p>This is contacts page...</p>
</div>

जब मैं कहता हूं कि आपके पास अन्य नियंत्रक हो सकते हैं, तो इसका मतलब है कि आप नियंत्रक को आंतरिक डोम तत्वों में प्लग कर सकते हैं, निम्नानुसार:

<div>
    <h3>Contacts</h3>
    <p ng-controller="anotherCtrl">Hello {{name}}! This is contacts page...     
    </p>
</div>

मुझे उम्मीद है कि इससे चीजें थोड़ी स्पष्ट होंगी।


इसलिए यदि आप <div ng-controller="FancyStuffController">एक बॉडी टैग के अंदर एक उदाहरण की घोषणा करते हैं, जो एक नियंत्रक को पहले से ही अपील करता है जैसे <body ng-controller="BodyController">यह काम करेगा? $apply already in progressजब मैं ऐसा करता हूं, तो त्रुटियों के बारे में सोचता हूं, लेकिन मुझे लगता है कि यह dpd.js. से संबंधित है ऐसा नहीं है, मुझे लगता है कि इसकी सिर्फ दो बार लोड हो रहा है या कुछ और, यकीन है कि कैसे नहीं, लेकिन नियंत्रक का मेरा उपयोग पुनः लोड करने की कोशिश कर रहा हो सकता है।
ब्लम्ब

1
@BrianThomas यकीन है, कि काम करना चाहिए। सावधान रहें: यदि आप किसी दृश्य में नियंत्रक को इंजेक्ट करना चाहते हैं, तो $ मार्गप्रोविडर का उपयोग करें, div टैग पर एनजी-नियंत्रक न लिखें।
अधरा २15

9

मैं वर्तमान में एकल पृष्ठ एप्लिकेशन बनाने की प्रक्रिया में हूं। यहाँ मेरे पास इस प्रकार है कि मुझे विश्वास है कि आपके प्रश्न का उत्तर होगा। मेरे पास एक बेस टेम्प्लेट (base.html) है जिसमें ng-viewनिर्देश के साथ एक div है। यह निर्देश कोणीय को बताता है कि नई सामग्री को कहां रखा जाए। ध्यान दें कि मैं खुद को कोणीय बना रहा हूं इसलिए मैं किसी भी तरह से यह नहीं कह रहा हूं कि यह सबसे अच्छा तरीका है।

app = angular.module('myApp', []);                                                                             

app.config(function($routeProvider, $locationProvider) {                        
  $routeProvider                                                                
       .when('/home/', {                                            
         templateUrl: "templates/home.html",                                               
         controller:'homeController',                                
        })                                                                      
        .when('/about/', {                                       
            templateUrl: "templates/about.html",     
            controller: 'aboutController',  
        }) 
        .otherwise({                      
            template: 'does not exists'   
        });      
});

app.controller('homeController', [              
    '$scope',                              
    function homeController($scope,) {        
        $scope.message = 'HOME PAGE';                  
    }                                                
]);                                                  

app.controller('aboutController', [                  
    '$scope',                               
    function aboutController($scope) {        
        $scope.about = 'WE LOVE CODE';                       
    }                                                
]); 

base.html

<html>
<body>

    <div id="sideMenu">
        <!-- MENU CONTENT -->
    </div>

    <div id="content" ng-view="">
        <!-- Angular view would show here -->
    </div>

<body>
</html>

वास्तव में, मैं एनजी-व्यू का भी उपयोग कर रहा हूं ताकि मैं अपने index.html में एक मुख्य.html का उपयोग कर सकूं। लेकिन आपके पास / घर और / के बारे में और दो नियंत्रक प्रत्येक के लिए हैं। मेरे पास केवल main.html के लिए ng-view के साथ index.html है। मैं मुख्य नियंत्रक के लिए दो नियंत्रकों को सेट कर सकता हूं जैसे कि आपने अपने साथ किया हैwhen /home

इस पोस्ट से पहले उत्तर पर एक नज़र डालें: stackoverflow.com/questions/17354568/…
ऑस्टिन

ठीक है, मुझे पता है कि कैसे और अधिक सेट करना है when। मुझे एक टेम्पलेट के लिए दो नियंत्रक चाहिए। या माबाई मुझे गलत समझा जो आप मुझे बताने की कोशिश कर रहे थे?

नियंत्रकों का उपयोग करने के बजाय निर्देशों का उपयोग करने का प्रयास करें। आप एक ही टेम्पलेट पर कई निर्देशों का उपयोग कर सकते हैं। यदि आप अभी भी अपने नियंत्रकों का उपयोग करना चाहते हैं, तो एक वीडियो है कि कैसे निर्देशक नियंत्रकों के साथ जुड़ सकते हैं: egghead.io/lessons/angularjs-directives-talking-to-controllers
Austin

6
<div class="widget" ng-controller="widgetController">
    <p>Stuff here</p>
</div>

<div class="menu" ng-controller="menuController">
    <p>Other stuff here</p>
</div>
///////////////// OR ////////////


  <div class="widget" ng-controller="widgetController">
    <p>Stuff here</p>
    <div class="menu" ng-controller="menuController">
        <p>Other stuff here</p>
    </div>
</div>

menuController में मेनू div के लिए उपयोग होता है। और widgetController दोनों के लिए उपयोग किया है।


यह सीधा लगता है, लेकिन कोई अपवाह नहीं है। यह सबसे अच्छा अभ्यास है, या बुरा है?
redfox05

1
आप क्या करेंगे, यदि आपके पास कई पृष्ठ हैं 100+ नियंत्रक! ... अस्पष्ट अभ्यास।
ArifMustafa

3

हम बस एक ही मॉड्यूल में एक से अधिक नियंत्रक की घोषणा कर सकते हैं। यहाँ एक उदाहरण है:

  <!DOCTYPE html>
    <html>

    <head>
       <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js">
       </script>
      <title> New Page </title>


    </head> 
    <body ng-app="mainApp"> <!-- if we remove ng-app the add book button [show/hide] will has no effect --> 
      <h2> Books </h2>

    <!-- <input type="checkbox" ng-model="hideShow" ng-init="hideShow = false"></input> -->
    <input type = "button" value = "Add Book"ng-click="hideShow=(hideShow ? false : true)"> </input>
     <div ng-app = "mainApp" ng-controller = "bookController" ng-if="hideShow">
             Enter book name: <input type = "text" ng-model = "book.name"><br>
             Enter book category: <input type = "text" ng-model = "book.category"><br>
             Enter book price: <input type = "text" ng-model = "book.price"><br>
             Enter book author: <input type = "text" ng-model = "book.author"><br>


             You are entering book: {{book.bookDetails()}}
     </div>

    <script>
             var mainApp = angular.module("mainApp", []);

             mainApp.controller('bookController', function($scope) {
                $scope.book = {
                   name: "",
                   category: "",
                   price:"",
                   author: "",


                   bookDetails: function() {
                      var bookObject;
                      bookObject = $scope.book;
                      return "Book name: " + bookObject.name +  '\n' + "Book category: " + bookObject.category + "  \n" + "Book price: " + bookObject.price + "  \n" + "Book Author: " + bookObject.author;
                   }

                };
             });
    </script>

    <h2> Albums </h2>
    <input type = "button" value = "Add Album"ng-click="hideShow2=(hideShow2 ? false : true)"> </input>
     <div ng-app = "mainApp" ng-controller = "albumController" ng-if="hideShow2">
             Enter Album name: <input type = "text" ng-model = "album.name"><br>
             Enter Album category: <input type = "text" ng-model = "album.category"><br>
             Enter Album price: <input type = "text" ng-model = "album.price"><br>
             Enter Album singer: <input type = "text" ng-model = "album.singer"><br>


             You are entering Album: {{album.albumDetails()}}
     </div>

    <script>
             //no need to declare this again ;)
             //var mainApp = angular.module("mainApp", []);

             mainApp.controller('albumController', function($scope) {
                $scope.album = {
                   name: "",
                   category: "",
                   price:"",
                   singer: "",

                   albumDetails: function() {
                      var albumObject;
                      albumObject = $scope.album;
                      return "Album name: " + albumObject.name +  '\n' + "album category: " + albumObject.category + "\n" + "Book price: " + albumObject.price + "\n" + "Album Singer: " + albumObject.singer;
                   }
                };
             });
    </script>

    </body>
    </html>

2

मैंने सिर्फ एक साधारण घोषणा पत्र दिया है

var app = angular.module("app", ["xeditable"]);

फिर मैंने एक सेवा और दो नियंत्रक बनाए

प्रत्येक नियंत्रक के लिए जेएस में मेरी एक पंक्ति थी

app.controller('EditableRowCtrl', function ($scope, CRUD_OperService) {

और HTML में मैंने आसपास के div में ऐप स्कोप घोषित किया

<div ng-app="app">

और प्रत्येक नियंत्रक गुंजाइश अलग से अपने स्वयं के डिव (अनुप्रयोग डिव के भीतर) में

<div ng-controller="EditableRowCtrl">

यह ठीक काम किया


0

आप अपने मुख्य HTML फ़ाइल में अपने सभी टेम्पलेट दृश्यों को एम्बेड कर सकते हैं। उदाहरण के लिए:

<body ng-app="testApp">
  <h1>Test App</h1>
  <div ng-view></div>
  <script type = "text/ng-template" id = "index.html">
    <h1>Index Page</h1>
    <p>{{message}}</p>
  </script>
  <script type = "text/ng-template" id = "home.html">
    <h1>Home Page</h1>
    <p>{{message}}</p>
  </script>
</body>

इस तरह यदि प्रत्येक टेम्पलेट को अलग नियंत्रक की आवश्यकता होती है तो आप अभी भी कोणीय-राउटर का उपयोग कर सकते हैं। एक कार्य उदाहरण के लिए इस प्लंक को देखें http://plnkr.co/edit/9X0fT0Q9MlXtHVQLhgr?p=preview

इस तरह एक बार एप्लिकेशन को आपके क्लाइंट से सर्वर पर भेजे जाने के बाद, यह पूरी तरह से आत्म निहित है कि यह किसी भी डेटा अनुरोध, आदि की आवश्यकता नहीं है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.