既然已经消除了$broadcast和$emit之间的性能差异,那么是否有理由偏爱$scope呢?$emit到$rootScope.$broadcast?

是的,他们是不同的。

$emit仅限于作用域层次结构(向上)——如果它适合您的设计,这可能很好,但在我看来这是一个相当武断的限制。

rootScope美元。$broadcast适用于所有选择收听事件的人,在我看来,这是一个更合理的限制。

我遗漏了什么吗?

编辑:

澄清一下,派遣的方向不是我所关注的问题。美元的范围。$emit向上分派事件,而$scope。$broadcast -向下。但是为什么不总是使用$rootScope呢?$broadcast能达到所有目标听众?


当前回答

它们所做的工作并不相同:$emit通过作用域层次结构向上分派事件,而$broadcast向下分派事件到所有子作用域。

其他回答

Tl;dr(这个Tl;dr来自下面@sp00m的答案)

$emit向上分派一个事件…$broadcast向下分派事件

详细解释

rootScope美元。$emit只允许其他$rootScope侦听器捕获它。当您不希望每个$scope都得到它时,这很好。主要是高层沟通。把它想象成成年人在房间里互相说话,这样孩子们就听不见了。

rootScope美元。$broadcast是一个让几乎所有东西都能听到它的方法。这就相当于父母大喊晚饭准备好了,让家里的每个人都听到了。

美元的范围。$emit是当你想要$scope及其所有父类和$rootScope听到事件时使用的。这是一个孩子在家里向父母抱怨(但不是在杂货店,因为其他孩子能听到)。

美元的范围。$broadcast用于$scope本身及其子域。这是一个孩子对着毛绒玩具窃窃私语,这样他们的父母就听不见了。

它们所做的工作并不相同:$emit通过作用域层次结构向上分派事件,而$broadcast向下分派事件到所有子作用域。

美元的范围。$emit:这个方法向上分发事件(从子对象到父对象)

美元的范围。方法向下(从父控制器到子控制器)分发事件到所有子控制器。

美元的范围。$on:方法注册监听某个事件。所有正在侦听该事件的控制器获得广播或发出的通知 这是孩子和父母之间的关系。

$emit事件可以被监听该事件的任何一个$作用域取消。

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

砰砰作响:https://embed.plnkr.co/0Pdrrtj3GEnMp2UpILp4/

对于兄弟作用域(不在直接父子层次结构中的作用域),则$emit和$broadcast将不会与兄弟作用域通信。

详情请参阅 http://yogeshtutorials.blogspot.in/2015/12/event-based-communication-between-angularjs-controllers.html

在服务中使用RxJS

例如,如果你有一个处于保持状态的服务。我如何将更改推送到该服务,以及页面上的其他随机组件如何知道此类更改?最近一直在努力解决这个问题

用RxJS扩展为Angular构建一个服务。

<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订阅更改。订阅和生产者可以通过DataService.set推送更改。

PLNKR上的演示。

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

正如这个答案所暗示的,

$broadcast/$on方法不是非常有效,因为它向所有作用域广播(在作用域层次结构的一个方向或两个方向)。而Pub/Sub方式要直接得多。只有订阅者才能获得事件,因此不需要到系统中的每个作用域才能使其工作。

你可以使用angular- pubsub angular模块。一旦你添加了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('事件名称');。

请不要忘记取消订阅,避免内存泄漏。