2016-05-05 11 views
10

के साथ निर्देशों के बीच Angularjs घटना संचार मैं कोणीय घटना प्रणाली के साथ एक प्रकाशन/सदस्यता प्रणाली बनाना चाहता हूँ।प्रकाशित/सब्सक्राइब

angular.module("app",[]); 

angular.module("app").directive("first", function($rootScope){ 
     return { 
      template: "First Directive", 
      link:function(scope,element,attribute){ 
       $rootScope.$broadcast("OnFirstDirectiveCreated", { 
       "message": "I'm first directive" 
      }); 
     } 
    } 
}) 

angular.module("app").directive("second", function($rootScope){ 
     return { 
      template: "Second Directive", 
      link:function(scope,element,attribute){ 
      var handler = $rootScope.$on("OnFirstDirectiveCreated", 
       function (event, args) { 
        console.log("First Directive Message: " + args.message); 
      }); 
     } 
    } 
}) 

अगर मैं इस तरह HTML दस्तावेज़ सेट, कोई संदेश कंसोल में नहीं दिखाई:

<div ng-app="app"> 
    <first></first> 
    <second></second> 
</div> 

अगर मैं कंसोल पर पहले और दूसरे क्रम बदलने के लिए, संदेश wirite।

<div ng-app="app"> 
    <second></second> 
    <first></first> 
</div> 

लेकिन मुझे पहले निर्देश या आंतरिक निर्देश की आवश्यकता है।

<div ng-app="app"> 
    <first></first> 
    <second></second> 
</div> 

<div ng-app="app"> 
    <first> 
     <second></second> 
    </first> 
</div> 

मैं दोनों $rootScope.$broadcast और $rootScope.$emit की कोशिश की लेकिन woeked नहीं किया।

Working DEMO

उत्तर

4

यह बिल्कुल सही कोणीय व्यवहार है।

पहले उदाहरण में:

<first></first> 
<second></second> 

कोणीय first टैग के लिए एक निर्देश बनाता है और तुरंत घटना भेजता है, लेकिन दूसरे के निर्देश अभी तक नहीं बनाया गया है।

दूसरे उदाहरण में:

<first></first> 
<second></second> 

यहाँ आप सबसे पहले एक घटना के लिए सदस्यता, और कहा कि first निर्देश के बाद एक संदेश भेजता है। इस वजह से, second निर्देश एक घटना स्वीकार करता है।

तीसरा उदाहरण:

<first> 
    <second></second> 
</first> 

यह मामला है, साथ ही पहला उदाहरण काम नहीं करने वाले।

समाधान: समाधानों में से एक सृजन के तुरंत बाद घटना न भेजने के लिए पहले निर्देश में टाइमआउट सेट करना है। $timeout, delay का दूसरा पैरामीटर प्रदान नहीं की है, तो डिफ़ॉल्ट व्यवहार फ़ंक्शन निष्पादित करने डोम प्रतिपादन पूरा कर लिया है के बाद है:

angular.module("app").directive("first", function($rootScope, $timeout) { 
    return { 
    template: "First Directive", 
    link: function(scope,element,attribute) { 
     $timeout(function() { 
     $rootScope.$broadcast("OnFirstDirectiveCreated", { 
      "message": "I'm first directive" 
     }) 
     }); 
    } 
    } 
}); 

Demo

+0

$ टाइमआउट 0 सेकंड थोड़ा उलझन में है। अगर मेरा दूसरा निर्देश कुछ सेकेंड लोड करता है, तो क्या कोई समस्या हो सकती है? हम अन्य निर्देश लोड समय को नहीं जान सकते हैं। – barteloma

+0

मैंने एक उत्तर अपडेट किया है, यदि आप 'देरी' पैरामीटर के बिना '$ टाइमआउट' का उपयोग करेंगे, तो डीओएम ने प्रतिपादन पूरा करने के बाद फ़ंक्शन निष्पादित किया जाएगा। – alexmac

1

यह इसलिए होता है क्योंकि जब पहले निर्देश का प्रसारण निष्पादित किया जाता है, दूसरा निर्देश तैयार नहीं है और इसलिए संकेत गुम हो गया है और संचार नहीं होता है। इसे हल करने का एक तरीका, $ अंतराल फ़ंक्शन का उपयोग करके सिग्नल को कई बार भेजना है और दूसरा निर्देश तैयार होने पर ही प्रेषण करना बंद कर देना है। बेशक दूसरे निर्देश को वापस प्रसारित करना होता है जब इसे पहले से डेटा प्राप्त होता है। दूसरा समाधान, जिसके लिए मैं जाऊंगा, दूसरे निर्देश के लिए यह सूचित करने के लिए है कि पहली बार रूट रूटस्कोप के साथ प्रसारण करके पहले निर्देश के लिए तैयार किया गया था जैसा आपने पहले निर्देश में किया था।

angular.module("app").directive("second", function($rootScope){ 
    return { 
     template: "Second Directive", 
     link:function(scope,element,attribute){ 
     var handler = $rootScope.$on("secondDirective", 
      function (event, args) { 
       console.log("First Directive Data: " + args); 
     }); 

     $rootScope.$broadcast("OnChildDirectiveCreated", { 
      "message": "I'm second directive", 
      "id":  "secondDirective" 
     }); 
     } 
    } 
}) 

और पहले निर्देश:

angular.module("app").directive("first", function($rootScope){ 
    return { 
     template: "First Directive", 
     link:function(scope,element,attribute){ 
      $rootScope.$on("OnChildDirectiveCreated", function(event, args) { 
       $rootScope.$broadcast(args.id, someData); 
      }); 
     } 
    } 
}) 

आप एक माता पिता के बच्चे संरचना का उपयोग कर रहे के बाद से, यह हमेशा की गारंटी है कि पहले निर्देश तैयार है जब बच्चे के निर्देशों के लिए तैयार हैं हो जाएगा। इस समाधान का उपयोग करके आप कई बच्चे के निर्देशों का उपयोग कर सकते हैं। उम्मीद है की यह मदद करेगा!