为什么我们在AngularJS中使用$ rootScope。$ broadcast?


109

试图找到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




$rootScope.$broadcast.apply()之所以使用,是因为如果要将特殊arguments对象传递给另一个函数,则需要使用apply()(而不是call())。除了@Blackhole可以在MDN页面上链接到Apply之外,您还可以查看上的条目arguments
Scott Schupbach '16

Answers:


97
  1. 怎么$rootScope.$broadcast办?

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

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

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

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

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


11
大有赶超上的$rootScope.$on内存泄漏。这也适用于已接受的答案,因为控制器很可能会调用hiEventService他创建的答案。
adamdport,2015年

在哪个示例中您将使用$broadcastvs$broadcast.apply()
访客

$ rootScope。$ broadcast将事件发送给所有侦听器,不仅是子作用域的侦听器。$ scope。$ broadcast将事件限制在子范围内
Geert Bellemans

157

$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)}
})

4
谢谢@itcouldevenbeabout这行代码不是调用将事件附加到全局$ rootScope的相同逻辑吗?function(){$ rootScope。$ broadcast(“ hi”)},您提到的这是不好的做法吗?
Nexus23 2014年

11
使用服务进行广播并为特定事件附加监听器,可以避免您不确定谁在监听。很清楚哪些组件将事件服务作为依赖项
CoolTapes 2014年

4
刚刚发现$ emit和$ broadcast之间的区别之后,我倾向于说$ emit事件会更好-这样,您可以在尽可能小的范围内污染事件(理想情况下,服务应具有这是自己的范围,但我认为不可能吗?)
Brondahl

3
-1。我看不到,服务中的隔离比单纯广播更好。无论如何,最好在服务中使用自己的私有范围。最好使用$ emit,而不是$ broadcast。此外,您建议的服务不支持事件参数。更糟糕的是,它不支持退订。$ rootScope的致命罪。
alpha-mouse

3
取消订阅的缺乏对我来说是个难题。如果hiEventService.listen(callback)从控制器调用,则即使销毁了控制器,侦听器仍将存在。内存泄漏!绑定到控制器范围$scope.$on("hi",callback)附带自动清除功能。
adamdport

32

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

根作用域广播事件:

$rootScope.$broadcast("myEvent");

任何子级Scope都可以侦听该事件:

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

为什么我们使用$ rootScope。$ broadcast?您可以$watch用来侦听变量更改,并在变量状态更改时执行功能。但是,在某些情况下,您只想引发一个事件,应用程序的其他部分可以侦听此事件,而不管作用域变量状态如何变化。这是$broadcast有帮助的。


19

传递数据!

我不知道为什么没有人提到$broadcast接受一个参数,您可以在其中传递一个Object将通过$on使用回调函数接收的 参数

例:

// the object to transfert
var myObject = {
    status : 10
}

$rootScope.$broadcast('status_updated', myObject);
$scope.$on('status_updated', function(event, obj){
    console.log(obj.status); // 10
})

8

$ rootScope。$ broadcast有什么作用?

它通过整个角度应用程序将消息广播到各个侦听器,这是将消息传输到不同层次级别的范围(父,子或同级)的一种非常强大的方法

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

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.