【问题标题】:Why do we use $rootScope.$broadcast in AngularJS?为什么我们在 AngularJS 中使用 $rootScope.$broadcast?
【发布时间】:2014-09-09 22:14:31
【问题描述】:

试图找到 AngularJS $rootScope.$broadcast 的一些基本信息,但是 AngularJS 文档并没有多大帮助。简单来说,我们为什么要使用它?

此外,在 John Papa 的 Hot Towel 模板中,在名为 $broadcast 的公共模块中有一个自定义函数:

function $broadcast() {
    return $rootScope.$broadcast.apply($rootScope, arguments);
}

我不明白这是在做什么。所以这里有几个基本问​​题:

1) $rootScope.$broadcast 是做什么的?

2)$rootScope.$broadcast$rootScope.$broadcast.apply有什么区别?

【问题讨论】:

标签: angularjs rootscope


【解决方案1】:

$rootScope 基本上用作事件侦听器和调度器。

回答如何使用的问题,结合rootScope.$on使用;

$rootScope.$broadcast("hi");

$rootScope.$on("hi", function(){
    //do something
});

但是,将$rootScope 用作您自己的应用程序的通用事件服务是一种不好的做法,因为您很快就会陷入每个应用程序都依赖于 $rootScope 的情况,并且您不知道哪些组件正在侦听什么事件。

最佳做法是为您想要收听或广播的每个自定义事件创建一个服务。

.service("hiEventService",function($rootScope) {
    this.broadcast = function() {$rootScope.$broadcast("hi")}
    this.listen = function(callback) {$rootScope.$on("hi",callback)}
})

【讨论】:

  • 谢谢@itcouldevenbeabout 这一行不是调用了将事件附加到全局 $rootScope 的相同逻辑吗?你提到的function() {$rootScope.$broadcast("hi")},这是一个不好的做法?
  • 使用服务进行广播并附加特定事件的侦听器可以避免您不确定谁在收听的情况。哪些组件将事件服务作为依赖项变得清晰
  • 刚刚发现了 $emit 和 $broadcast 之间的区别,我倾向于说 $emit 事件会更好 - 这样您的事件会在尽可能小的集合中造成污染范围,(理想情况下,服务应该有自己的范围,但我认为这不可能?)
  • -1。我不明白,服务中的隔离比简单的广播要好得多。无论如何,最好在服务中使用自己的私有范围。最好使用 $emit,而不是 $broadcast。此外,您提出的服务不支持事件参数。更糟糕的是它不支持退订; $rootScope 的大罪。
  • 没有退订对我来说毁了这个答案。如果从控制器调用hiEventService.listen(callback),即使控制器被销毁,监听器仍然存在。内存泄漏!绑定到控制器范围 $scope.$on("hi",callback) 带有自动清理功能。
【解决方案2】:

$rootScope.$broadcast 有什么作用?

它将消息广播到整个 Angular 应用程序的各个侦听器,这是一种非常强大的方法,可以将消息传输到不同层次级别的范围(无论是父级、子级还是兄弟级)

同样,我们有 $rootScope.$emit,唯一的区别是前者也被 $scope.$on 捕获,而后者仅被 $rootScope.$on 捕获。

参考示例:- http://toddmotto.com/all-about-angulars-emit-broadcast-on-publish-subscribing/

【讨论】:

    【解决方案3】:

    $rootScope.$broadcast 是引发所有子作用域都可以侦听的“全局”事件的便捷方式。您只需要使用$rootScope 来广播消息,因为所有后代范围都可以监听它。

    根作用域广播事件:

    $rootScope.$broadcast("myEvent");
    

    任何子 Scope 都可以监听事件:

    $scope.$on("myEvent",function () {console.log('my event occurred');} );
    

    我们为什么使用 $rootScope.$broadcast? 您可以使用$watch 来监听变量变化,并在变量状态变化时执行函数。但是,在某些情况下,您只想引发应用程序的其他部分可以侦听的事件,而不管范围变量状态的任何变化。这时候$broadcast 就派上用场了。

    【讨论】:

      【解决方案4】:
      1. $rootScope.$broadcast 是做什么的?

        $rootScope.$broadcast 正在通过应用程序范围发送事件。 该应用程序的任何子范围都可以使用简单的方法捕获它:$scope.$on()

        当您想要到达不是直接父级的范围(例如父级的分支)时,发送事件特别有用

        !!!但是,不要做的一件事是使用控制器中的$rootScope.$on$rootScope 是应用程序,当你的控制器被销毁时,事件监听器仍然存在,当你的控制器被再次创建时,它只会堆积更多的事件监听器。 (因此一个广播将被多次捕获)。改用$scope.$on(),监听器也会被销毁。

      2. $rootScope.$broadcast$rootScope.$broadcast.apply 有什么区别?

        有时您必须使用apply(),尤其是在使用指令和其他 JS 库时。但是,由于我不知道该代码库,因此我无法判断这里是否是这种情况。

      【讨论】:

      • 很好地解决了$rootScope.$on 内存泄漏问题。这也适用于接受的答案,因为控制器可能会调用他创建的hiEventService
      • 什么是您将使用$broadcast$broadcast.apply() 的示例
      • $rootScope.$broadcast 将事件发送给所有侦听器,而不仅仅是子范围的侦听器。 $scope.$broadcast 将事件限制在子范围内
      【解决方案5】:

      传递数据!!!

      我想知道为什么没有人提到$broadcast 接受一个可以传递Object 的参数

      示例:

      // the object to transfert
      var obj = {
          status : 10
      }
      
      $rootScope.$broadcast('status_updated', obj);
      
      $scope.$on('status_updated', function(event, obj){
          console.log(obj.status); // 10
      })
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-03-16
        • 1970-01-01
        • 2016-06-09
        • 1970-01-01
        相关资源
        最近更新 更多