Every application has a single root scope. All other scopes are descendant scopes of the root scope. Scopes provide separation between the model and the view, via a mechanism for watching the model for changes. They also provide event emission/broadcast and subscription facility.一個ng-app只會有一個 $rootScope,所有的 $scope 都是 $rootScope 的child scope。文件特別把angular的emission/broadcast機制放在定義,這也代表事件處理是 $rootScope 很重要的操作。
$scope.$emit up, $scope.$broadcast down
// firing an event upwards
$scope.$emit('myCustomEvent', 'Data to send');
// firing an event downwards
$scope.$broadcast('myCustomEvent', {
someProp: 'Sending you an Object!' // send whatever you want
});
// listen for the event in the relevant $scope
$scope.$on('myCustomEvent', function (event, data) {
console.log(data); // 'Data to send'
});
簡單說明這三個行為
- $emit 往上(parent)觸發事件
- $broadcast 往下(child)觸發事件
- $on 當收到事件所執行的行為
但是$scope的互動並非都是parent-child關係,有可能是Sibling之間要觸發。這時候就會要先$emit parentScope在$broadcast,並不是很方便的寫法。
$scope.$parent.$broadcast('myevent', 'Some data');
$rootScope.($emit/$broadcast)
上面的這種sibling的事件觸發,則可以使用$rootScope代為處理,如下方案例。
簡單說明 $rootScope 的 $emit 跟 $broadcast 的差別。
簡單說明 $rootScope 的 $emit 跟 $broadcast 的差別。
- $rootScope.$emit 因為$rootScope沒有父層,所以直接觸發 $rootScope 註冊的事件。
- $rootScope.$broadcast 往下廣播事件。
<div ng-controller="ParentCtrl as parent" class="ng-scope">
// ParentCtrl
<div ng-controller="SiblingOneCtrl as sib1" class="ng-scope">
// SiblingOneCtrl
</div>
<div ng-controller="SiblingTwoCtrl as sib2" class="ng-scope">
// SiblingTwoCtrl
<div ng-controller="ChildCtrl as child" class="ng-scope">
// ChildCtrl
</div>
</div>
</div>
app.controller('SiblingOneCtrl',
function SiblingOneCtrl ($rootScope) {
$rootScope.$on('rootScope:emit', function (event, data) {
console.log(data); // 'Emit!'
});
$scope.$on('rootScope:broadcast', function (event, data) {
console.log(data); // 'Broadcast!'
});
$rootScope.$on('rootScope:broadcast', function (event, data) {
console.log(data); // 'Broadcast!'
});
});
app.controller('ChildCtrl',
function ChildCtrl ($rootScope) {
$rootScope.$emit('rootScope:emit', 'Emit!'); // $rootScope.$on
$rootScope.$broadcast('rootScope:broadcast', 'Broadcast'); // $rootScope.$on && $scope.$on
});
Ref.1 AngularJS Offical Document: $rootScope
Ref.2 Understanding Angular’s $scope and $rootScope event system $emit, $broadcast and $on