संपादित करें : इस उत्तर में संबोधित मुद्दे को angular.js संस्करण 1.2.7 में हल किया गया है । $broadcast
अब अपंजीकृत स्कोप पर बुदबुदाहट से बचा जाता है और $ उतनी ही तेजी से चलता है।
तो, अब आप कर सकते हैं:
- से उपयोग
$broadcast
करें$rootScope
- घटना के बारे में जानने के
$on
लिए स्थानीय से$scope
उपयोग करके सुनें
मूल उत्तर नीचे
मैं अत्यधिक सलाह देता हूं कि $rootScope.$broadcast
+ का उपयोग न करें $scope.$on
बल्कि $rootScope.$emit
+ $rootScope.$on
। पूर्व में गंभीर प्रदर्शन समस्याओं का कारण हो सकता है जैसा कि @numan द्वारा उठाया गया है। ऐसा इसलिए है क्योंकि घटना सभी scopes के माध्यम से नीचे बुलबुला जाएगा ।
हालांकि, बाद के (का उपयोग कर $rootScope.$emit
+ $rootScope.$on
) करता नहीं इस से ग्रस्त है और इसलिए एक तेजी से संचार चैनल के रूप में इस्तेमाल किया जा सकता!
के कोणीय प्रलेखन से $emit
:
एक घटना के नाम को ऊपर की ओर गुंजाइश के माध्यम से प्रेषित करता है जो पदानुक्रम पंजीकृत को सूचित करता है
चूंकि ऊपर कोई गुंजाइश नहीं है $rootScope
, इसलिए कोई हलचल नहीं हो रही है। यह उपयोग करने के लिए पूरी तरह से सुरक्षित है $rootScope.$emit()
/ $rootScope.$on()
एक EventBus के रूप में।
हालांकि, नियंत्रक के भीतर से इसका उपयोग करते समय एक गोचा है। यदि आप सीधे $rootScope.$on()
किसी कंट्रोलर से बंधते हैं, तो आपको अपने स्थानीय $scope
को नष्ट होने पर बंधन को स्वयं साफ करना होगा । इसका कारण यह है कि नियंत्रकों (सेवाओं के विपरीत) एक आवेदन के जीवनकाल में कई बार त्वरित रूप से प्राप्त कर सकते हैं, जिसके परिणामस्वरूप अंत में सभी जगह स्मृति लीक बनाने के लिए बाध्य होने का योग होगा :)
अपंजीकृत लिए, बस अपने पर सुनने $scope
की $destroy
और घटना तो समारोह है कि द्वारा दिया गया था कहते हैं $rootScope.$on
।
angular
.module('MyApp')
.controller('MyController', ['$scope', '$rootScope', function MyController($scope, $rootScope) {
var unbind = $rootScope.$on('someComponent.someCrazyEvent', function(){
console.log('foo');
});
$scope.$on('$destroy', unbind);
}
]);
मैं कहूंगा, यह वास्तव में एक कोणीय विशिष्ट बात नहीं है क्योंकि यह अन्य EventBus कार्यान्वयनों पर भी लागू होता है, आपको संसाधनों को साफ करना होगा।
हालाँकि, आप उन मामलों के लिए अपना जीवन आसान बना सकते हैं। उदाहरण के लिए, आप बंदर को पैच कर सकते हैं $rootScope
और उसे दे सकते हैं, जो स्थानीय पर नष्ट हो जाने $onRootScope
पर $rootScope
सीधे हैंडलर को साफ करता है $scope
।
इस $rootScope
तरह की $onRootScope
विधि प्रदान करने के लिए बंदर पैच को साफ करने का सबसे अच्छा तरीका एक डेकोरेटर के माध्यम से होगा (एक रन ब्लॉक शायद इसे ठीक भी करेगा लेकिन psstst, किसी को भी न बताएं)
यह सुनिश्चित करने के लिए कि $onRootScope
जब $scope
हम उपयोग करते हैं Object.defineProperty()
और सेट करते हैं , तो संपत्ति अप्रत्याशित नहीं दिखाई देती enumerable
है false
। ध्यान रखें कि आपको ES5 शिम की आवश्यकता हो सकती है।
angular
.module('MyApp')
.config(['$provide', function($provide){
$provide.decorator('$rootScope', ['$delegate', function($delegate){
Object.defineProperty($delegate.constructor.prototype, '$onRootScope', {
value: function(name, listener){
var unsubscribe = $delegate.$on(name, listener);
this.$on('$destroy', unsubscribe);
return unsubscribe;
},
enumerable: false
});
return $delegate;
}]);
}]);
इस विधि के साथ ऊपर से कंट्रोलर कोड को सरल बनाया जा सकता है:
angular
.module('MyApp')
.controller('MyController', ['$scope', function MyController($scope) {
$scope.$onRootScope('someComponent.someCrazyEvent', function(){
console.log('foo');
});
}
]);
तो इस सब के अंतिम परिणाम के रूप में मैं आपको $rootScope.$emit
+ का उपयोग करने की अत्यधिक सलाह देता हूं $scope.$onRootScope
।
Btw, मैं कोणीय कोर के भीतर समस्या को संबोधित करने के लिए कोणीय टीम को समझाने की कोशिश कर रहा हूं। यहाँ एक चर्चा चल रही है: https://github.com/angular/angular.js/issues/4574
यहाँ एक jsperf है जो दिखाता है कि एक बढ़िया प्रभाव $broadcast
मात्र 100 के साथ एक परिपूर्ण परिदृश्य में तालिका में लाता है $scope
।
http://jsperf.com/rootscope-emit-vs-rootscope-broadcast