क्या एक AngularJS कंट्रोलर दूसरे को कॉल कर सकता है?


581

क्या एक नियंत्रक दूसरे का उपयोग करना संभव है?

उदाहरण के लिए:

यह HTML डॉक्यूमेंट फाइल MessageCtrlमें कंट्रोलर द्वारा दिए गए संदेश को प्रिंट करता messageCtrl.jsहै।

<html xmlns:ng="http://angularjs.org/">
<head>
    <meta charset="utf-8" />
    <title>Inter Controller Communication</title>
</head>
<body>
    <div ng:controller="MessageCtrl">
        <p>{{message}}</p>
    </div>

    <!-- Angular Scripts -->
    <script src="http://code.angularjs.org/angular-0.9.19.js" ng:autobind></script>
    <script src="js/messageCtrl.js" type="text/javascript"></script>
</body>
</html>

नियंत्रक फ़ाइल में निम्न कोड है:

function MessageCtrl()
{
    this.message = function() { 
        return "The current date is: " + new Date().toString(); 
    };
}

जो बस वर्तमान तिथि को प्रिंट करता है;

अगर मैं एक अन्य नियंत्रक को जोड़ना चाहता था, DateCtrlजो एक विशिष्ट प्रारूप में तारीख को वापस सौंपता है MessageCtrl, तो यह करने के बारे में कैसे जाना जाएगा? डीआई फ्रेमवर्क XmlHttpRequestsसेवाओं से संबंधित और पहुंच से संबंधित प्रतीत होता है ।


4
यह Google समूह थ्रेड, group.google.com/d/topic/angular/m_mn-8gnNt4/discussion , चर्चा करता है कि 5 तरीके नियंत्रक एक दूसरे से बात कर सकते हैं।
मार्क राजकॉक

यहां पहले से ही अच्छे उत्तर हैं, इसलिए मैं केवल यह बताना चाहूंगा कि विशेष रूप से उपयोग किए गए मामले के लिए, शायद एक AngularJS फ़िल्टर एक बेहतर समाधान होगा? बस मैंने सोचा कि मैं इसका उल्लेख
करूंगा

जवाबों:


705

नियंत्रकों के बीच संवाद करने के कई तरीके हैं।

सबसे अच्छा शायद एक सेवा साझा कर रहा है:

function FirstController(someDataService) 
{
  // use the data service, bind to template...
  // or call methods on someDataService to send a request to server
}

function SecondController(someDataService) 
{
  // has a reference to the same instance of the service
  // so if the service updates state for example, this controller knows about it
}

एक अन्य तरीका स्कोप पर एक घटना का उत्सर्जन कर रहा है:

function FirstController($scope) 
{
  $scope.$on('someEvent', function(event, args) {});
  // another controller or even directive
}

function SecondController($scope) 
{
  $scope.$emit('someEvent', args);
}

दोनों ही मामलों में, आप किसी भी निर्देश के साथ संवाद कर सकते हैं।


4
हिया, पहले उदाहरण के लिए वेब पेज को स्टैक में सभी सेवाओं के बारे में पता होना चाहिए। जो एक बुरी गंध (?) की तरह लगता है। दूसरे के साथ के रूप में, वेब पेज $ गुंजाइश तर्क प्रदान करने की आवश्यकता नहीं होगी?
बैंक्ससीयन

54
क्या? क्यों? सभी नियंत्रकों को एंगुलर के डीआई द्वारा इंजेक्ट किया जाता है।
वोज्टा

7
@JoshNoe 1 में / आपके पास दो नियंत्रक (या अधिक) हैं और वे दोनों एक समान / साझा सेवा प्राप्त करते हैं। फिर, आपके पास संवाद करने के कई तरीके हैं, जिनमें से कुछ का आपने उल्लेख किया है। मैं आपके विशिष्ट उपयोग के मामले के आधार पर निर्णय लूंगा। आप साझा तर्क / राज्य को सेवा में रख सकते हैं और दोनों नियंत्रक केवल उस सेवा को सौंप सकते हैं या सेवा को टेम्पलेट में निर्यात कर सकते हैं। बेशक, यह सेवा भी आग लगा सकती है ...
वोज्टा

137
इस देर से आ रहा है: आप लोग जानते हैं कि आप Google से The Vojta के साथ बहस कर रहे हैं जो AngularJS पर काम करता है, है ना? :)
सुमन

16
मेरे लिए यह स्पष्ट नहीं था कि मेरे HTML में ईवेंट-एमिटिंग कंट्रोलर को काम करने के लिए सुनने वाले नियंत्रक का बच्चा-नोड होना चाहिए।
djangonaut

122

इस फिडेल को देखें: http://jsfiddle.net/simpulton/XqDxG/

निम्न वीडियो भी देखें: नियंत्रकों के बीच संवाद

एचटीएमएल:

<div ng-controller="ControllerZero">
  <input ng-model="message" >
  <button ng-click="handleClick(message);">LOG</button>
</div>

<div ng-controller="ControllerOne">
  <input ng-model="message" >
</div>

<div ng-controller="ControllerTwo">
  <input ng-model="message" >
</div>

जावास्क्रिप्ट:

var myModule = angular.module('myModule', []);
myModule.factory('mySharedService', function($rootScope) {
  var sharedService = {};

  sharedService.message = '';

  sharedService.prepForBroadcast = function(msg) {
    this.message = msg;
    this.broadcastItem();
  };

  sharedService.broadcastItem = function() {
    $rootScope.$broadcast('handleBroadcast');
  };

  return sharedService;
});

function ControllerZero($scope, sharedService) {
  $scope.handleClick = function(msg) {
    sharedService.prepForBroadcast(msg);
  };

  $scope.$on('handleBroadcast', function() {
    $scope.message = sharedService.message;
  });        
}

function ControllerOne($scope, sharedService) {
  $scope.$on('handleBroadcast', function() {
    $scope.message = 'ONE: ' + sharedService.message;
  });        
}

function ControllerTwo($scope, sharedService) {
  $scope.$on('handleBroadcast', function() {
    $scope.message = 'TWO: ' + sharedService.message;
  });
}

ControllerZero.$inject = ['$scope', 'mySharedService'];        

ControllerOne.$inject = ['$scope', 'mySharedService'];

ControllerTwo.$inject = ['$scope', 'mySharedService'];

12
उपरोक्त फिडेल और वीडियो एक सेवा को साझा करते हैं। यहाँ एक
फिडेल है

1
@adardesign: मैं निर्देश के लिए एक ही रसीला और सार्थक उदाहरण पढ़ने के लिए प्यार करता हूँ (इस जवाब के लिए भी धन्यवाद!)
sscarduzio

महान जवाब, मैं myModule.factory के बजाय myModule.service ('mySaringService', फ़ंक्शन ($ rootScope) {}) का उपयोग करता हूं, लेकिन यह किसी से भी कम काम नहीं करता है!
TacoEater

अति उत्कृष्ट। हालाँकि, मेरे पास एक सवाल है: आपने कंट्रोलरजेरो के भीतर एक हैंडलर क्यों जोड़ा? $ स्कोप। $ पर ('हैंडलब्रॉडकास्ट', फंक्शन () {$ स्कोप.मेज़ेज = शेअरसेव्स.मैसेज;});
चिड़ियाघर १०

प्रदान किया गया वीडियो वास्तव में बहुत बढ़िया है! मुझे लगता है कि यह वही है जो मुझे किसी अन्य नियंत्रक से किसी अन्य नियंत्रक की स्थिति की पूछताछ करने की आवश्यकता है। हालांकि, यह "इनवोक" फ़ंक्शन का उपयोग करके काम नहीं करता है। यह "ट्रिगर" कार्रवाई का उपयोग करके काम करता है। इतनी प्रभावी रूप से, यदि कोई नियंत्रक कोई कार्रवाई करता है, और उसके पास एक नया राज्य है, तो, उसे राज्य को प्रसारित करना होगा, और यह उस प्रसारण को सुनने और तदनुसार प्रतिक्रिया करने के लिए अन्य नियंत्रकों पर निर्भर है। या बेहतर, साझा सेवा में कार्रवाई करें, फिर राज्य को प्रसारित करें। अगर मेरी समझ सही है तो कृपया मुझे बताएं।
तारेकह सेफ़

53

यदि आप एक नियंत्रक को दूसरे में बुलाना चाहते हैं तो चार विधियाँ उपलब्ध हैं

  1. $ rootScope। $ emit () और $ rootScope। $ प्रसारण ()
  2. यदि दूसरा नियंत्रक बच्चा है, तो आप पेरेंट चाइल्ड कम्युनिकेशन का उपयोग कर सकते हैं।
  3. सेवाओं का उपयोग करें
  4. हैक की तरह - angular.element () की मदद से

1. $ rootScope। $ Emit () और $ rootScope। $ प्रसारण ()

नियंत्रक और इसका दायरा नष्ट हो सकता है, लेकिन $ rootScope आवेदन भर में बना हुआ है, इसीलिए हम $ rootScope ले रहे हैं क्योंकि $ rootScope सभी स्कोपों ​​का जनक है।

यदि आप माता-पिता से बच्चे तक संचार कर रहे हैं और यहां तक ​​कि बच्चा अपने भाई-बहनों के साथ संवाद करना चाहता है, तो आप $ प्रसारण का उपयोग कर सकते हैं

यदि आप बच्चे से माता-पिता तक संचार कर रहे हैं, तो किसी भाई-बहन का चालान नहीं हुआ है तो आप $ rootScope का उपयोग कर सकते हैं। $ em।

एचटीएमएल

<body ng-app="myApp">
    <div ng-controller="ParentCtrl" class="ng-scope">
      // ParentCtrl
      <div ng-controller="Sibling1" class="ng-scope">
        // Sibling first controller
      </div>
      <div ng-controller="Sibling2" class="ng-scope">
        // Sibling Second controller
        <div ng-controller="Child" class="ng-scope">
          // Child controller
        </div>
      </div>
    </div>
</body>

कोणीयज कोड

 var app =  angular.module('myApp',[]);//We will use it throughout the example 
    app.controller('Child', function($rootScope) {
      $rootScope.$emit('childEmit', 'Child calling parent');
      $rootScope.$broadcast('siblingAndParent');
    });

app.controller('Sibling1', function($rootScope) {
  $rootScope.$on('childEmit', function(event, data) {
    console.log(data + ' Inside Sibling one');
  });
  $rootScope.$on('siblingAndParent', function(event, data) {
    console.log('broadcast from child in parent');
  });
});

app.controller('Sibling2', function($rootScope) {
  $rootScope.$on('childEmit', function(event, data) {
    console.log(data + ' Inside Sibling two');
  });
  $rootScope.$on('siblingAndParent', function(event, data) {
    console.log('broadcast from child in parent');
  });
});

app.controller('ParentCtrl', function($rootScope) {
  $rootScope.$on('childEmit', function(event, data) {
    console.log(data + ' Inside parent controller');
  });
  $rootScope.$on('siblingAndParent', function(event, data) {
    console.log('broadcast from child in parent');
  });
});

$ Emit के उपरोक्त कोड कंसोल में 'चाइल्ड इमिट' बाल भाई-बहनों के अंदर कॉल नहीं करेगा और यह केवल माता-पिता के अंदर कॉल करेगा, जहाँ $ प्रसारण को भाई-बहन और माता-पिता के अंदर भी कहा जाता है। यह वह स्थान है जहाँ प्रदर्शन एक क्रिया में आते हैं। $ emit। बेहतर, अगर आप बच्चे को माता-पिता के संचार के लिए उपयोग कर रहे हैं क्योंकि यह कुछ गंदे चेक को छोड़ देता है।

2. यदि दूसरा नियंत्रक बच्चा है, तो आप बाल अभिभावक संचार का उपयोग कर सकते हैं

इसकी एक सबसे अच्छी विधि, यदि आप बाल अभिभावक संचार करना चाहते हैं, जहाँ बच्चा तत्काल माता-पिता के साथ संवाद करना चाहता है - तो उसे किसी भी प्रकार के $ प्रसारण या $ emit की आवश्यकता नहीं होगी, लेकिन यदि आप माता-पिता से बच्चे तक संचार करना चाहते हैं तो आपको सेवा या $ प्रसारण का उपयोग करें

उदाहरण के लिए HTML: -

<div ng-controller="ParentCtrl">
 <div ng-controller="ChildCtrl">
 </div>
</div>

AngularJS

 app.controller('ParentCtrl', function($scope) {
   $scope.value='Its parent';
      });
  app.controller('ChildCtrl', function($scope) {
   console.log($scope.value);
  });

जब भी आप माता-पिता के संचार के लिए बच्चे का उपयोग कर रहे हैं, तो एंगुलरज बच्चे के अंदर एक चर की खोज करेंगे, अगर यह अंदर मौजूद नहीं है तो यह माता-पिता के नियंत्रक के अंदर के मूल्यों को देखना पसंद करेगा।

3. सेवाओं का उपयोग करें

एंगुलरजेएस सेवाओं की वास्तुकला का उपयोग करके "सेपरेशन ऑफ कंसर्न" की अवधारणाओं का समर्थन करता है । सेवाएं जावास्क्रिप्ट फ़ंक्शंस हैं और केवल एक विशिष्ट कार्य करने के लिए ज़िम्मेदार हैं। यह उन्हें एक व्यक्तिगत इकाई बनाता है जो बनाए रखने योग्य और परीक्षण करने योग्य है । एंगुलरज की डिपेंडेंसी इंजेक्शन mecahnism का उपयोग करके इंजेक्शन लगाने के लिए उपयोग की जाने वाली सेवाएं।

कोणीयज कोड:

app.service('communicate',function(){
  this.communicateValue='Hello';
});

app.controller('ParentCtrl',function(communicate){//Dependency Injection
  console.log(communicate.communicateValue+" Parent World");
});

app.controller('ChildCtrl',function(communicate){//Dependency Injection
  console.log(communicate.communicateValue+" Child World");
});

यह आउटपुट हैलो चाइल्ड वर्ल्ड और हैलो पैरेंट वर्ल्ड देगा। सेवाओं के एंगुलर डॉक्स के अनुसार सिंगलनेट्स - सेवा पर निर्भर प्रत्येक घटक को सेवा कारखाने द्वारा उत्पन्न एकल उदाहरण का संदर्भ मिलता है

4. हैक की - angular.element () की मदद से

इस विधि को इसके Id / unique class.angular.element () विधि रिटर्न एलिमेंट द्वारा स्कोप () मिल जाता है और स्कोप और स्कोप) एक स्कोप के दूसरे स्कोप वैरिएबल का उपयोग करके दूसरे वैरिएबल का $ स्कोप वैरिएबल देता है, यह एक अच्छा प्रैक्टिस नहीं है।

एचटीएमएल: -

<div id='parent' ng-controller='ParentCtrl'>{{varParent}}
 <span ng-click='getValueFromChild()'>Click to get ValueFormChild</span>
 <div id='child' ng-controller='childCtrl'>{{varChild}}
   <span ng-click='getValueFromParent()'>Click to get ValueFormParent </span>
 </div>
</div>

AngularJS: -

app.controller('ParentCtrl',function($scope){
 $scope.varParent="Hello Parent";
  $scope.getValueFromChild=function(){
  var childScope=angular.element('#child').scope();
  console.log(childScope.varChild);
  }
});

app.controller('ChildCtrl',function($scope){
 $scope.varChild="Hello Child";
  $scope.getValueFromParent=function(){
  var parentScope=angular.element('#parent').scope();
  console.log(parentScope.varParent);
  }
}); 

ऊपर के कोड में नियंत्रक एचटीएमएल पर अपना मान दिखा रहे हैं और जब आप पाठ पर क्लिक करेंगे, तो आपको कंसोल में मान उसी हिसाब से मिलेंगे। यदि आप अभिभावक नियंत्रकों की अवधि पर क्लिक करते हैं, तो ब्राउज़र बच्चे और उपाध्यक्ष के मूल्य को सांत्वना देगा।


52

सेवा डेटा साझा करने वाले दो नियंत्रकों का एक-पृष्ठ उदाहरण यहां दिया गया है:

<!doctype html>
<html ng-app="project">
<head>
    <title>Angular: Service example</title>
    <script src="http://code.angularjs.org/angular-1.0.1.js"></script>
    <script>
var projectModule = angular.module('project',[]);

projectModule.factory('theService', function() {  
    return {
        thing : {
            x : 100
        }
    };
});

function FirstCtrl($scope, theService) {
    $scope.thing = theService.thing;
    $scope.name = "First Controller";
}

function SecondCtrl($scope, theService) {   
    $scope.someThing = theService.thing; 
    $scope.name = "Second Controller!";
}
    </script>
</head>
<body>  
    <div ng-controller="FirstCtrl">
        <h2>{{name}}</h2>
        <input ng-model="thing.x"/>         
    </div>

    <div ng-controller="SecondCtrl">
        <h2>{{name}}</h2>
        <input ng-model="someThing.x"/>             
    </div>
</body>
</html>

यहां भी: https://gist.github.com/3595424


और यदि theServiceअपडेट किया जाता है thing.x, तो यह परिवर्तन स्वचालित रूप से <input> s FirstCtrlऔर SecondCtrl, सही में प्रचारित करता है ? और कोई भी thing.xदो <input> s (दाएं?) में से किसी के माध्यम से सीधे बदल सकता है ।
KajMagnus

4
हाँ। सभी कोणीय सेवाएं अनुप्रयोग एकल हैं, जिसका अर्थ है कि सेवा का केवल एक उदाहरण है। संदर्भ: docs.angularjs.org/guide/dev_guide.services.creating_services
exclsr

मेरी पिछली टिप्पणी में लिंक 404 है, इसलिए यहां सेवाओं का मार्गदर्शक है, आज, कि नोट्स सेवाएं एकल
22

1
@exclsr हाँ! क्षमा करें, इससे पहले मैं चूक गया था
CodyBugstein

3
अब तक का सबसे अच्छा उदाहरण मैंने वेब पर देखा है। धन्यवाद
Sevenearths

33

यदि आप नियंत्रकों में डेटा या कॉल फ़ंक्शन साझा करने के लिए ईवेंट्स को प्रसारित और प्रसारित करना चाहते हैं , तो कृपया इस लिंक को देखें : और zbynour(अधिकतम वोटों के साथ उत्तर) द्वारा उत्तर की जांच करें । मैं उसका जवाब उद्धृत कर रहा हूँ !!!

अगर फर्स्टक्लाट का स्कोप सेकंडक्रेटल स्कोप का जनक है, तो आपके कोड को फर्स्टक्राट्ल में $ एमिकट द्वारा $ emit को बदलकर काम करना चाहिए:

function firstCtrl($scope){
    $scope.$broadcast('someEvent', [1,2,3]);
}

function secondCtrl($scope){
    $scope.$on('someEvent', function(event, mass) {console.log(mass)});
}

यदि आपके स्कॉप्स के बीच कोई पेरेंट-चाइल्ड रिलेशन नहीं है, तो आप कंट्रोलर में $ $ रूटस्कोप इंजेक्ट कर सकते हैं और ईवेंट को सभी चाइल्ड स्कॉप्स (यानी सेकंडक्रेटल) पर भी प्रसारित कर सकते हैं।

function firstCtrl($rootScope){
    $rootScope.$broadcast('someEvent', [1,2,3]);
}

अंत में, जब आपको इवेंट को चाइल्ड कंट्रोलर से स्कोप तक भेजने की आवश्यकता होती है, तो आप $ स्कोप का उपयोग कर सकते हैं। $ emit। यदि फर्स्टक्लाट का स्कोप दूसरे करंट स्कोप का जनक है:

function firstCtrl($scope){
    $scope.$on('someEvent', function(event, data) { console.log(data); });
}

function secondCtrl($scope){
    $scope.$emit('someEvent', [1,2,3]);
}

24

दो और पहेलियां: (गैर सेवा दृष्टिकोण)

1) $scopeपेरेंट के लिए- चाइल्ड कंट्रोलर - ईवेंट / ब्रॉडकास्ट इवेंट्स के लिए पेरेंट कंट्रोलर का इस्तेमाल करना । http://jsfiddle.net/laan_sachin/jnj6y/

2) $rootScopeगैर-संबंधित नियंत्रकों का उपयोग करना । http://jsfiddle.net/VxafF/


घटनाओं के साथ इस सारी जटिलता का क्या कारण है? कुछ ऐसा क्यों नहीं करते? jsfiddle.net/jnj6y/32
Dfr

यह इस बात पर निर्भर करता है कि माता-पिता का किस तरह का रिश्ता सही है। यह एक डोम उत्तराधिकार हो सकता है, यह मामला घटनाओं आप चीजों को कम करने की अनुमति होगी।
DarkKnight

17

वास्तव में उत्सर्जन और प्रसारण का उपयोग करना अक्षम है, क्योंकि घटना के दायरे और पदानुक्रम में बुलबुले होते हैं जो आसानी से एक जटिल अनुप्रयोग के लिए प्रदर्शन टोंटी में नीचा दिखा सकता है।

मैं एक सेवा का उपयोग करने का सुझाव दूंगा। यहाँ मैंने हाल ही में इसे अपनी एक परियोजना में कैसे लागू किया है - https://gist.github.com/3384419

मूल विचार - सेवा के रूप में पब-उप / इवेंट बस को पंजीकृत करें। फिर उस इवेंट बस को इंजेक्ट करें जहाँ आपको कभी भी घटनाओं / विषयों की सदस्यता लेने या प्रकाशित करने की आवश्यकता है।


5

मुझे इस तरह से भी पता है।

angular.element($('#__userProfile')).scope().close();

लेकिन मैं इसका बहुत अधिक उपयोग नहीं करता, क्योंकि मुझे कोणीय कोड में jQuery के चयनकर्ताओं का उपयोग करना पसंद नहीं है।


सबसे अच्छा जवाब। इतना सरल और आसान ... =)
zVictor

3
@zVictor, यह वास्तव में एक "अंतिम उपाय" प्रकार है। यह काम करता है, लेकिन अपने तरीके को वापस करने के लिए यह गुंजाइश से बाहर हो रहा है। यह DOM मैनिपुलेशन का उपयोग करके प्रोग्राम के बजाय कुछ करने के लिए मजबूर करने के लिए उपयोग कर रहा है। यह सरल है, यह काम करता है, लेकिन यह स्केलेबल नहीं है।
ब्रायन नूह

2
@BrianNoah, सच। यह प्रोटोटाइप या कुछ प्रयोगों के लिए इस कोड का उपयोग करना ठीक है, लेकिन उत्पादन कोड के लिए नहीं।
एंड्रे कोरचैक

1
यह सबसे बुरा है जो किया जा सकता है। सेवाओं में डोम हेरफेर और प्रत्यक्ष गुंजाइश पहुंच।
मटिया फ्रेंचेटो

3

एक विधि है जो सेवाओं पर निर्भर नहीं है, $broadcastया $emit। यह सभी मामलों में उपयुक्त नहीं है, लेकिन यदि आपके पास 2 संबंधित नियंत्रक हैं जो निर्देशों में सार हो सकते हैं, तो आप requireनिर्देश परिभाषा में विकल्प का उपयोग कर सकते हैं । यह सबसे अधिक संभावना है कि ngModel और ngForm कैसे संवाद करते हैं। आप इसका उपयोग निर्देशक नियंत्रकों के बीच संवाद करने के लिए कर सकते हैं जो या तो नेस्टेड हैं, या एक ही तत्व पर।

माता-पिता / बच्चे की स्थिति के लिए, उपयोग निम्नानुसार होगा:

<div parent-directive>
  <div inner-directive></div>
</div>

और इसे प्राप्त करने के लिए मुख्य बिंदु: माता-पिता के निर्देश पर, बुलाया जाने वाले तरीकों के साथ, आपको उन्हें परिभाषित करना चाहिए this(नहीं पर $scope:)

controller: function($scope) {
  this.publicMethodOnParentDirective = function() {
    // Do something
  }
}

चाइल्ड डायरेक्टिव डेफिनेशन पर, आप requireविकल्प का उपयोग कर सकते हैं इसलिए पैरेंट कंट्रोलर को लिंक फंक्शन में पास कर दिया जाता है (इसलिए आप scopeउस पर चाइल्ड डायरेक्शन से फंक्शन कॉल कर सकते हैं ।

require: '^parentDirective',
template: '<span ng-click="onClick()">Click on this to call parent directive</span>',
link: function link(scope, iElement, iAttrs, parentController) {
  scope.onClick = function() {
    parentController.publicMethodOnParentDirective();
  }
}

ऊपर http://plnkr.co/edit/poeq460VmQER8Gl9w8Oz?p=preview पर देखा जा सकता है

एक सिबलिंग निर्देश का उपयोग समान रूप से किया जाता है, लेकिन एक ही तत्व पर दोनों निर्देश:

<div directive1 directive2>
</div>

पर एक विधि बनाकर उपयोग किया जाता है directive1:

controller: function($scope) {
  this.publicMethod = function() {
    // Do something
  }
}

और निर्देश 2 में इसे उस requireविकल्प का उपयोग करके बुलाया जा सकता है जिसके परिणामस्वरूप सिबलिंगकंट्रोलर को लिंक फ़ंक्शन में पास किया जा सकता है:

require: 'directive1',
template: '<span ng-click="onClick()">Click on this to call sibling directive1</span>',
link: function link(scope, iElement, iAttrs, siblingController) {
  scope.onClick = function() {
    siblingController.publicMethod();
  }
}

इसे http://plnkr.co/edit/MUD2snf9zvadfnDXq85w?p=preview पर देखा जा सकता है ।

इस का उपयोग करता है?

  • माता-पिता: कोई भी मामला जहां बाल तत्वों को माता-पिता के साथ खुद को "पंजीकृत" करने की आवश्यकता होती है। बहुत पसंद है ngModel और ngForm के बीच संबंध। ये कुछ व्यवहार जोड़ सकते हैं जो मॉडल को प्रभावित कर सकते हैं। आपके पास कुछ विशुद्ध रूप से DOM आधारित हो सकता है, जहां एक अभिभावक तत्व को कुछ बच्चों के पदों को प्रबंधित करने की आवश्यकता होती है, स्क्रॉल करने के लिए प्रबंधन या प्रतिक्रिया करने के लिए कहें।

  • सहोदर: एक निर्देश को अपने व्यवहार को संशोधित करने की अनुमति देता है। ngModel इनपुट पर ngModel का उपयोग करने के लिए पार्सर्स / सत्यापन जोड़ने के लिए क्लासिक मामला है।


3

मुझे नहीं पता कि यह मानकों से बाहर है लेकिन अगर आपके पास एक ही फाइल पर आपके सभी नियंत्रक हैं, तो आप कुछ इस तरह से कर सकते हैं:

app = angular.module('dashboardBuzzAdmin', ['ngResource', 'ui.bootstrap']);

var indicatorsCtrl;
var perdiosCtrl;
var finesCtrl;

app.controller('IndicatorsCtrl', ['$scope', '$http', function ($scope, $http) {
  indicatorsCtrl = this;
  this.updateCharts = function () {
    finesCtrl.updateChart();
    periodsCtrl.updateChart();
  };
}]);

app.controller('periodsCtrl', ['$scope', '$http', function ($scope, $http) {
  periodsCtrl = this;
  this.updateChart = function() {...}
}]);

app.controller('FinesCtrl', ['$scope', '$http', function ($scope, $http) {
  finesCtrl = this;
  this.updateChart = function() {...}
}]);

जैसा कि आप देख सकते हैं कि संकेतककटरलैट, अपडेटचार्ट्स को कॉल करते समय अन्य दोनों नियंत्रकों के अपडेटहार्ट फ़ंक्शंस को कॉल कर रहा है।


2

आप अपने मूल नियंत्रक (MessageCtrl) में '$ कंट्रोलर' सेवा को इंजेक्ट कर सकते हैं और फिर बच्चे नियंत्रक (DateCtrl) को तुरंत उपयोग / इंजेक्ट कर सकते हैं:
$scope.childController = $controller('childController', { $scope: $scope.$new() });

अब आप अपने चाइल्ड कंट्रोलर से इसके तरीकों को कॉल करके डेटा एक्सेस कर सकते हैं क्योंकि यह एक सेवा है।
अगर कोई मुद्दा है तो मुझे बताएं।


1

निम्नलिखित एक publish-subscribeदृष्टिकोण है जो कि एंगुलर जेएस के बावजूद है।

परम नियंत्रक खोजें

//Note: Multiple entities publish the same event
regionButtonClicked: function () 
{
        EM.fireEvent('onSearchParamSelectedEvent', 'region');
},

plantButtonClicked: function () 
{
        EM.fireEvent('onSearchParamSelectedEvent', 'plant');
},

खोज विकल्प नियंत्रक

//Note: It subscribes for the 'onSearchParamSelectedEvent' published by the Search Param Controller
localSubscribe: function () {
        EM.on('onSearchParamSelectedEvent', this.loadChoicesView, this);

});


loadChoicesView: function (e) {

        //Get the entity name from eData attribute which was set in the event manager
        var entity = $(e.target).attr('eData');

        console.log(entity);

        currentSelectedEntity = entity;
        if (entity == 'region') {
            $('.getvalue').hide();
            this.loadRegionsView();
            this.collapseEntities();
        }
        else if (entity == 'plant') {
            $('.getvalue').hide();
            this.loadPlantsView();
            this.collapseEntities();
        }


});

कार्यक्रम प्रबंधक

myBase.EventManager = {

    eventArray:new Array(),


    on: function(event, handler, exchangeId) {
        var idArray;
        if (this.eventArray[event] == null) {
            idArray = new Array();
        } else { 
            idArray = this.eventArray[event];
        }
        idArray.push(exchangeId);
        this.eventArray[event] = idArray;

        //Binding using jQuery
        $(exchangeId).bind(event, handler);
    },

    un: function(event, handler, exchangeId) {

        if (this.eventArray[event] != null) {
            var idArray = this.eventArray[event];
            idArray.pop(exchangeId);
            this.eventArray[event] = idArray;

            $(exchangeId).unbind(event, handler);
        }
    },

    fireEvent: function(event, info) {
        var ids = this.eventArray[event];

        for (idindex = 0; idindex < ids.length; idindex++) {
            if (ids[idindex]) {

                //Add attribute eData
                $(ids[idindex]).attr('eData', info);
                $(ids[idindex]).trigger(event);
            }
        }
    }
};

वैश्विक

var EM = myBase.EventManager;

1

कोणीय 1.5 में निम्न कार्य करके इसे पूरा किया जा सकता है:

(function() {
  'use strict';

  angular
    .module('app')
    .component('parentComponent',{
      bindings: {},
      templateUrl: '/templates/products/product.html',
      controller: 'ProductCtrl as vm'
    });

  angular
    .module('app')
    .controller('ProductCtrl', ProductCtrl);

  function ProductCtrl() {
    var vm = this;
    vm.openAccordion = false;

    // Capture stuff from each of the product forms
    vm.productForms = [{}];

    vm.addNewForm = function() {
      vm.productForms.push({});
    }
  }

}());

यह मूल घटक है। इसमें मैंने एक ऐसा फंक्शन बनाया है जो किसी अन्य ऑब्जेक्ट को मेरे productFormsएरे - नोट में धकेलता है - यह सिर्फ मेरा उदाहरण है, यह फंक्शन वास्तव में कुछ भी हो सकता है।

अब हम एक और घटक बना सकते हैं जो इसका उपयोग करेगा require:

(function() {
  'use strict';

  angular
    .module('app')
    .component('childComponent', {
      bindings: {},
      require: {
        parent: '^parentComponent'
      },
      templateUrl: '/templates/products/product-form.html',
      controller: 'ProductFormCtrl as vm'
    });

  angular
    .module('app')
    .controller('ProductFormCtrl', ProductFormCtrl);

  function ProductFormCtrl() {
    var vm = this;

    // Initialization - make use of the parent controllers function
    vm.$onInit = function() {
      vm.addNewForm = vm.parent.addNewForm;
    };  
  }

}());

यहां चाइल्ड कंपोनेंट माता-पिता के कंपोनेंट फंक्शन के लिए एक रेफरेंस बना रहा है, addNewFormजिसे बाद में एचटीएमएल में बांधा जा सकता है और इसे किसी दूसरे फंक्शन की तरह कहा जा सकता है।

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