我目前使用一个可怕的软糖涉及窗口:
function StockSubgroupCtrl($scope,$http) { $scope.subgroups = []; $scope.handleSubgroupsLoaded = function(data,status) { $scope.subgroups = data; } $scope.fetch = function(prod_grp) { $http.get('/api/stock/groups/' + prod_grp + '/subgroups/').success($scope.handleSubgroupsLoaded); } window.fetchStockSubgroups = $scope.fetch; } function StockGroupCtrl($scope,$http) { ... $scope.select = function(prod_grp) { $scope.selectedGroup = prod_grp; window.fetchStockSubgroups(prod_grp); } }
所以,现在你可以:
>使用$ broadcast从$ rootScope
> listen使用$ on从需要知道事件的本地$ scope
原始答案下面
我强烈建议不要使用$ rootScope。$ broadcast $ scope。$ on,而是$ rootScope。$ emit $ rootScope。$ on。前者可能导致严重的性能问题,由@numan提出。这是因为事件将向下滚动通过所有范围。
但是,后者(使用$ rootScope。$ emit $ rootScope。$ on)没有这种情况,因此可以用作快速通信通道!
从$ emit的angular文档:
Dispatches an event name upwards through the scope hierarchy notifying the registered
因为没有范围超过$ rootScope,没有冒泡发生。使用$ rootScope。$ emit()/ $ rootScope。$ on()作为EventBus是完全安全的。
但是,在控制器中使用它时有一个困扰。如果你直接绑定到控制器中的$ rootScope。$ on(),你必须在你的局部$ scope被销毁时自己清除绑定。这是因为控制器(与服务相反)可以在应用程序的生命周期内被实例化多次,这将导致绑定总结,最终在整个地方创建内存泄漏:)
要取消注册,只需监听$ scope的$ destroy事件,然后调用$ rootScope。$ on返回的函数。
angular .module('MyApp') .controller('MyController',['$scope','$rootScope',function MyController($scope,$rootScope) { var unbind = $rootScope.$on('someComponent.someCrazyEvent',function(){ console.log('foo'); }); $scope.$on('$destroy',unbind); } ]);
我会说,这不是一个真正的角度具体的事情,因为它也适用于其他EventBus实现,以及,你必须清理资源。
但是,你可以让你的生活更轻松的情况下。例如,你可以猴子补丁$ rootScope并给它一个$ onRootScope订阅$ rootScope上发出的事件,但也直接清除处理程序时,局部$ scope被销毁。
最纯洁的方式猴子补丁$ rootScope提供这样的$ onRootScope方法将通过一个装饰器(一个运行块可能会做它只是罚款,但pssst,不告诉任何人)
为了确保$ onRootScope属性在枚举超过$ scope时不会出现意外,我们使用Object.defineProperty()并将enumerable设置为false。请记住,您可能需要一个ES5垫片。
angular .module('MyApp') .config(['$provide',function($provide){ $provide.decorator('$rootScope',['$delegate',function($delegate){ Object.defineProperty($delegate.constructor.prototype,'$onRootScope',{ value: function(name,listener){ var unsubscribe = $delegate.$on(name,listener); this.$on('$destroy',unsubscribe); return unsubscribe; },enumerable: false }); return $delegate; }]); }]);
angular .module('MyApp') .controller('MyController',function MyController($scope) { $scope.$onRootScope('someComponent.someCrazyEvent',function(){ console.log('foo'); }); } ]);
所以作为所有这些的最终结果,我强烈建议您使用$ rootScope。$ emit $ scope。$ onRootScope。
Btw,我试图说服有角度的团队解决角核心内的问题。这里有一个讨论:https://github.com/angular/angular.js/issues/4574
这里是一个jsperf,显示多少影响$ broadcastbrings到表在一个体面的场景,只有100 $范围。