控制器未收到$ broadcast事件

时间:2014-07-28 15:38:12

标签: angularjs events global broadcast

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

$rootScope.$broadcast('MyEvent', 'message');

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

4 个答案:

答案 0 :(得分:10)

这是预期的行为。当您的部分视图具有与之关联的各个控制器时,仅当呈现视图时控制器才在范围内。只有在解析了myEvent指令时,控制器才会进入范围在部分视图中。只有在加载与其关联的视图后,才能期望控制器在范围内。

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

看到这个明显地在你的angular.element('[ng-controller=urControllerName]').scope()步骤上设置断点并暂停执行以检查控制台中 ./myApp ├── api ├── assets ├── ... ├── test │ ├── unit │ │ ├── controllers │ │ │ └── UsersController.test.js │ │ ├── models │ │ │ └── Users.test.js │ │ └── ... │ ├── fixtures │ ├── ... │ ├── bootstrap.test.js │ └── mocha.opts └── views 的值,你可以看到它是未定义的意味着控制器还没有在适用范围。

答案 1 :(得分:2)

如果你包含更多的代码会有所帮助,因为有正确的方法和错误的方式来执行$ on(),而你的速记将是错误的方式。我看到有人曾经认为这回复了一个承诺,并试图使用.then()就可以了。需要回调:

$rootScope.$on('MyEvent', function(myParam) {
    alert(myParam);
});

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

通常,当您想要在特定范围内放置某些内容及其子项时,您会使用$ broadcast,例如,当您在数据表行中的兄弟节点之间发布事件或类似事件时。 (悬停效果,对行的数据更新,那种事情......)

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

答案 2 :(得分:1)

我遇到了同样的问题,因为我正在使用通过ng-include包含的视图中声明的控制器,这样简单:

<div ng-include="'pageToInclude.view.html'" ></div>

pageToInclude包含:

<div class="header" ng-controller="pageCtrl as pageCtrl">.......</div>

我的问题是该事件在此页面呈现之前被清除,因此它没有捕获此事件,所以我所做的只是在ng-include的div中声明控制器,如下所示:

<div ng-include="'pageToInclude.view.html'" ng-controller="pageCtrl as pageCtrl"></div>

当然会从页面内删除ng-controller。

希望我的回答可以帮助那些人,欢呼。

答案 3 :(得分:0)

使用$ scope的$ apply方法。

/* Service.js */
$rootScope.$broadcast('MyEvent', 'message');


/* Controller.js */
$rootScope.$on("MyEvent", function(event, args){

  // works!
  alert("Event!");

  // not works!
  $scope.message = args[0];

  // works!
  $scope.$apply(function(){
    $scope.message = args[0];
  });
});