Sunting : Masalah yang dibahas dalam jawaban ini telah diatasi dalam angular.js versi 1.2.7 . $broadcastsekarang hindari menggelegak atas cakupan yang tidak terdaftar dan berjalan secepat $ emit.

Jadi, sekarang Anda dapat:
- gunakan
$broadcastdari$rootScope
- dengarkan menggunakan
$on dari lokal$scope yang perlu tahu tentang acara tersebut
Jawaban Asli Di Bawah Ini
Saya sangat menyarankan untuk tidak menggunakan $rootScope.$broadcast+ $scope.$onmelainkan $rootScope.$emit+ $rootScope.$on. Yang pertama dapat menyebabkan masalah kinerja serius seperti yang diangkat oleh @numan. Itu karena acara tersebut akan menyebar melalui semua ruang lingkup.
Namun, yang terakhir (menggunakan $rootScope.$emit+ $rootScope.$on) tidak menderita ini dan karena itu dapat digunakan sebagai saluran komunikasi yang cepat!
Dari dokumentasi sudut $emit:
Mengirim nama acara ke atas melalui hierarki lingkup yang memberitahukan yang terdaftar
Karena tidak ada ruang lingkup di atas $rootScope, tidak ada gelembung yang terjadi. Sangat aman untuk menggunakan $rootScope.$emit()/ $rootScope.$on()sebagai EventBus.
Namun, ada satu gotcha saat menggunakannya dari dalam Controllers. Jika Anda langsung mengikat $rootScope.$on()dari dalam controller, Anda harus membersihkan sendiri mengikat ketika lokal Anda $scopehancur. Ini karena pengontrol (berbeda dengan layanan) dapat dipakai berkali-kali selama masa aplikasi yang akan menghasilkan binding yang akhirnya membuat kebocoran memori di semua tempat :)
Untuk unregister, hanya mendengarkan pada Anda $scope's $destroyacara dan kemudian memanggil fungsi yang dikembalikan oleh $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);
}
]);
Saya akan mengatakan, itu bukan hal yang sangat spesifik karena berlaku untuk implementasi EventBus lain juga, bahwa Anda harus membersihkan sumber daya.
Namun, Anda dapat membuat hidup Anda lebih mudah untuk kasus-kasus itu. Misalnya, Anda dapat menambal monyet $rootScopedan memberikannya $onRootScopeyang berlangganan acara yang dipancarkan di $rootScopetetapi juga secara langsung membersihkan pawang ketika lokal $scopedihancurkan.
Cara paling bersih untuk menambal monyet $rootScopeuntuk memberikan $onRootScopemetode seperti itu akan melalui dekorator (blok run mungkin akan melakukannya dengan baik juga tapi pssst, jangan bilang siapa-siapa)
Untuk memastikan $onRootScopeproperti tidak muncul secara tak terduga saat menghitung lebih dari, $scopekami menggunakan Object.defineProperty()dan mengatur enumerableuntuk false. Perlu diingat bahwa Anda mungkin memerlukan shim 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;
}]);
}]);
Dengan metode ini, kode pengontrol dari atas dapat disederhanakan menjadi:
angular
.module('MyApp')
.controller('MyController', ['$scope', function MyController($scope) {
$scope.$onRootScope('someComponent.someCrazyEvent', function(){
console.log('foo');
});
}
]);
Jadi sebagai hasil akhir dari semua ini saya sangat menyarankan Anda untuk menggunakan $rootScope.$emit+ $scope.$onRootScope.
Btw, saya mencoba meyakinkan tim sudut untuk mengatasi masalah dalam inti sudut. Ada diskusi yang terjadi di sini: https://github.com/angular/angular.js/issues/4574
Berikut adalah jsperf yang menunjukkan berapa banyak dampak perf yang $broadcastdibawa ke meja dalam skenario yang layak hanya dengan 100 $scope's.
http://jsperf.com/rootscope-emit-vs-rootscope-broadcast
