提问



现在已经消除了$broadcast$emit之间的性能差异,是否有理由偏好$scope.$emit$rootScope.$broadcast?


他们是不同的,是的。


$emit仅限于范围层次结构(向上) - 如果它符合您的设计,这可能是好的,但在我看来这是一个相当随意的限制。


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


我错过了什么吗?


修改


为了回答答案,发送的方向不是我之后的问题。$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本身及其子女。这是一个子对它的毛绒动物窃窃私语,所以他们的父听不到。

其它参考1


他们没有做同样的工作:$emit通过范围层次结构发送事件向上,而$broadcast向所有子范围调度事件向下

其它参考2


我通过以下链接制作了以下图片:https://toddmotto.com/all-about-angulars-emit-broadcast-on-publish-subscribing/[40]


[41]


正如你所看到的,$rootScope.$broadcast$scope.$emit听到的听众多得多。


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

其它参考3


[42]


$ scope。$ emit:此方法向上调度事件(从子节点到父节点)



$ scope。$ broadcast:方法向下调度事件(从父节点到子节点)到所有子控制器。[43]



$ scope。$ on:用于监听某些事件的方法寄存器。所有正在收听该事件的控制器都会收到广播通知或基于此发出
那些适合子 - 父级层次结构的地方。 [44]


$ emit事件可以被正在监听事件的$ scope取消。


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


Plunker:https://embed.plnkr.co/0Pdrrtj3GEnMp2UpILp4/[45]


对于兄弟范围(范围不在直接父子层次结构中),$ emit和$ broadcast将不与兄弟范围进行通信。


[46]


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

其它参考4


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


正如这个答案所暗示的,



  $ broadcast/$ on方法不是非常有效,因为它广播到所有范围(在Scope层次结构的一个方向或两个方向上)。 Pub/Sub方法更直接。只有订阅者才能获得事件,所以它不会到系统的每个范围来使其工作。



你可以使用angular-PubSub角度模块。将PubSub模块添加到您的应用依赖项后,您可以使用PubSub服务订阅和取消订阅事件/主题。[49]


易于订阅:


// 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');


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

其它参考5


在服务中使用RxJS




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



使用RxJS Extensions for Angular构建服务。[50]


<script src="//unpkg.com/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上的DEMO。[51]