所以我有一个带有几个局部视图和每个局部视图一个控制器的angularjs应用程序。我还有一个服务,它将从$ rootScope广播事件:
$rootScope.$broadcast('MyEvent', 'message');
目前只有一个控制器监听事件,我注意到如果我不在与该控制器关联的视图上(通过路由),那么该控制器中永远不会收到该事件,因此从不加载视图与之相关联。无论哪个视图处于活动状态,如何确保控制器接收事件广播?我尝试在我的控制器中使用$scope.$on('MyEvent')
...和$rootScope.$on('MyEvent')
...似乎都不起作用。
答案 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];
});
});