$ rootScope。$ broadcast与$ scope。$ emit

既然$broadcast$emit之间的性能差异已经被消除了,那么是否有理由select$scope.$emit to $rootScope.$broadcast

他们是不同的,是的。

$emit只限于作用域层次结构(向上) – 如果它符合你的devise,这可能是好的,但在我看来,这是一个相当随意的限制。

$rootScope.$broadcast适用于所有select收听该事件,这在我看来是一个更明智的限制。

我错过了什么吗?

编辑:

为了澄清回答,调度的方向不是我所追求的问题。 $scope.$emit向上发送事件, $scope.$broadcast – 向下。 但为什么不总是使用$rootScope.$broadcast来达到所有预期的监听器呢?

tl; dr (这个tl; dr来自@ sp00m的答案)

$emit发送一个事件向上… $broadcast向下发送一个事件

详细的解释

$rootScope.$emit只允许其他$rootScope侦听器捕获它。 当你不希望每个$scope都能得到时,这是很好的。 主要是高层次的沟通。 想想大人们在一个房间里互相交谈,孩子们听不到他们的声音。

$rootScope.$broadcast是一种让所有东西都能听到的方法。 这就相当于家长大吼大叫晚饭已经准备好了,所以家里的每个人都听到了。

$scope.$emit是当你想要$scope和它的所有父母和$rootScope来听到事件。 这是一个在家里抱怨父母的孩子(但不是在其他孩子可以听到的杂货店里)。

$scope.$broadcast是用于$scope本身及其子节点的。 这是一个小孩耳语,所以他们的父母听不到。

他们没有做同样的工作: $emit通过作用域层次向上调度一个事件,而$broadcast 向下调度一个事件到所有的子作用域。

我从以下链接中提取了以下graphics: https : //toddmotto.com/all-about-angulars-emit-broadcast-on-publish-subscribeing/

范围,rootScope,发出,播放

正如你所看到的, $rootScope.$broadcast$scope.$emit有更多的监听器。

另外, $scope.$emit的冒泡效果可以被取消,而$rootScope.$broadcast不能。

在这里输入图像说明

$ scope。$ emit:这个方法向上调度事件(从child到parent)

在这里输入图像说明 $ scope。$ broadcast:方法将事件向下(从父到子)分派给所有子控制器。

在这里输入图像说明 $ scope。$ on:方法寄存器来监听某个事件。 所有正在监听该事件的控制器都将获得广播的通知,或者根据父子层次中适合的地方发出广播通知。

$ emit事件可以被正在监听事件的$ scope中的任何一个取消。

$ on提供了“stopPropagation”方法。 通过调用此方法,可以停止事件进一步传播。

Plunker: https ://embed.plnkr.co/0Pdrrtj3GEnMp2UpILp4/

在兄弟范围的情况下(范围不在直接的父子层次结构中),那么$ emit和$ broadcast将不会传递给兄弟范围。

在这里输入图像说明

有关更多详细信息,请参阅http://yogeshtutorials.blogspot.in/2015/12/event-based-communication-between-angularjs-controllers.html

艾迪给出了这个问题的完美答案。 但我想提请注意使用Pub / Sub的更有效的方法。

正如这个答案所示,

$ broadcast / $ on方法并不是非常有效,因为它向所有范围进行广播(既可以在一个方向上,也可以在两个方向上进行)。 而Pub / Sub方法更直接。 只有订阅者才能获取事件,因此系统中的所有范围都无法使其工作。

您可以使用angular-PubSubangular度模块。 一旦将PubSub模块添加到您的应用程序依赖项中,就可以使用PubSub服务来订阅和取消订阅事件/主题。

容易订阅:

 // Subscribe to event var sub = PubSub.subscribe('event-name', function(topic, data){ }); 

易于发布

 PubSub.publish('event-name', { prop1: value1, prop2: value2 }); 

要取消订阅,请使用PubSub.unsubscribe(sub);PubSub.unsubscribe('event-name');

注意不要忘记取消订阅以避免内存泄漏。

在服务中使用RxJS

如果你有一个服务,例如持有状态的情况下。 我怎样才能将更改推送到该服务,并在页面上的其他随机组件意识到这样的变化? 近来一直在努力解决这个问题

使用RxJS Extensions for Angular构build服务。

 <script src="angular/angular.js"></script> <script src="//unpkg.com/rx/dist/rx.all.js"></script> <script src="//unpkg.com/rx-angular/dist/rx.angular.js"></script> 
 var app = angular.module('myApp', ['rx']); app.factory("DataService", function(rx) { var subject = new rx.Subject(); var data = "Initial"; return { set: function set(d){ data = d; subject.onNext(d); }, get: function get() { return data; }, subscribe: function (o) { return subject.subscribe(o); } }; }); 

然后只需订阅更改。

 app.controller('displayCtrl', function(DataService) { var $ctrl = this; $ctrl.data = DataService.get(); var subscription = DataService.subscribe(function onNext(d) { $ctrl.data = d; }); this.$onDestroy = function() { subscription.dispose(); }; }); 

客户可以使用DataService.subscribe订阅更改,生产者可以使用DataService.set推送更改。

PLNKR上的演示 。