控制器未收到$ broadcast事件

use*_*636 7 events global broadcast angularjs

所以我有一个angularjs应用程序,每个局部视图有几个局部视图和一个控制器.我还有一个服务,它将从$ rootScope广播事件:

$rootScope.$broadcast('MyEvent', 'message');
Run Code Online (Sandbox Code Playgroud)

目前只有一个控制器监听事件,我注意到如果我不在与该控制器关联的视图上(通过路由),那么该控制器中永远不会收到该事件,因此从不加载与之关联的视图.无论哪个视图处于活动状态,如何确保控制器接收事件广播?我尝试在我的控制器中使用$scope.$on('MyEvent')...和$rootScope.$on('MyEvent')...; 似乎都不起作用.

Div*_* MV 10

这是预期的行为.由于您的部分视图具有与之关联的单独控制器,因此控制器仅在呈现视图时才在范围内.只有在部分视图ng-controller中解析了指令时,控制器才会进入范围.所以期望您的控制器仅在加载与其关联的视图后才在范围内.

在您myEvent使用$rootScope.$broadcast('MyEvent', 'message');您想要接收的控制器广播事件的情况下,此事件不在范围内.

看到这一点清楚地在你的broadcast步骤上设置一个断点并暂停执行以检查angular.element('[ng-controller=urControllerName]').scope()控制台中的值,你可以看到它将是未定义的,这意味着控制器尚未在范围内.


Cha*_*son 3

如果您包含更多的代码将会有所帮助,因为执行 $on() 有正确的方法和错误的方法,并且您的简写方式将是错误的方法。我曾经看到有人认为这会返回一个承诺,并尝试对其使用 .then() ,但这行不通。需要回调:

$rootScope.$on('MyEvent', function(myParam) {
    alert(myParam);
});
Run Code Online (Sandbox Code Playgroud)

另外,如果您正在进行 pub/sub 类型的工作,请注意 $emit 和 $broadcast 之间的区别。出于效率原因,这很重要,如果您不需要实际使用 $broadcast,您可能需要重新考虑它。$broadcast 将在该范围以及所有子范围上发送消息。这意味着 Angular 需要递归地迭代每个范围来寻找事件的侦听器。如果您使用大量指令(其中许多都有 scopy)和 ngRepeats,您可能会拥有数千个!

通常,当您想要故意将某些内容放在特定范围及其子范围内时,例如当您在数据表行中的同级之间发布事件或类似的内容时,您可以使用 $broadcast 。(悬停效果,数据更新到行,诸如此类的事情......)

你可以做的是使用 $emit。这以同样的方式工作(您仍然使用 $on 来监听它),但这次它沿着作用域链上升。这意味着如果您在 $rootScope 上启动它,它只会命中一个快速侦听器列表并在那里停止 - 如果您在同一级别注册 $on() 事件,那么它会非常快速且高效。在这种情况下,您将使用 $rootScope.$on() 而不是 $scope.$on()...但效率的提高是值得的!

  • 这非常有用,但我不认为这是问题的答案。控制器中的发布/订阅仅适用于活动视图。 (2认同)