如何在AngularJS中将广播事件注销到rootcope?

我有以下几点:

angular.module('test') .controller('QuestionsStatusController1', ['$rootScope', '$scope', '$resource', '$state', function ($rootScope, $scope, $resource, $state) { $scope.action2 = function() { $rootScope.$broadcast('action2@QuestionStatusController1'); } }]); angular.module('test') .controller('QuestionsStatusController2', ['$rootScope', '$scope', '$resource', '$state', function ($rootScope, $scope, $resource, $state) { $rootScope.$on('action2@QuestionStatusController1', function { //write your listener here }) }]); 

这是我的理解,我需要取消注册听力事件。 有人能告诉我如何编码/这样做吗?

如果你不注销事件,你会得到一个内存泄漏,因为你传递给$on的函数不会被清除(因为它的引用依然存在)。 更重要的是,任何在其作用域中引用的variables也将被泄漏。 如果您的控制器在应用程序中被多次创build/销毁,这将导致您的函数被多次调用。 幸运的是,AngularJS提供了一些有用的方法来避免内存泄漏和不必要的行为:

  • $on方法返回一个可以被调用来取消注册事件监听器的函数。 您将要保存您的注销function作为variables供以后使用: var cleanUpFunc = $scope.$on('yourevent', ...); 请参阅$on的文档: http : //docs.angularjs.org/api/ng.$ro​​otScope.Scope#$on

  • 每当一个范围在Angular中被清除(即一个控制器被销毁),一个$destroy事件就被触发了。 你可以注册到$scope$destroy事件并从那里调用你的cleanUpFunc

您可以将这两个有用的东西结合在一起来正确地清理您的订阅。 我把这个例子放在一起: http : //plnkr.co/edit/HGK9W0VJGip6fhYQQBCg?p=preview 。 如果你注释掉这行cleanUpFunc(); 然后点击切换button并执行button几次,您会注意到我们的事件处理程序被多次调用,这并不是真正需要的。

现在,在所有这些之后,为了使您的具体情况正确行事,只需将您的代码在QuestionsStatusController2更改为以下内容:

 angular.module('test') .controller('QuestionsStatusController2', ['$rootScope', '$scope', '$resource', '$state', function ($rootScope, $scope, $resource, $state) { var cleanUpFunc = $rootScope.$on('action2@QuestionStatusController1', function { //write your listener here }); $scope.$on('$destroy', function() { cleanUpFunc(); }); }]); 

通过在$destroy调用cleanUpFunc() ,您的action2@QuestionStatusController1事件的事件侦听器将被取消订阅,并且当您的控制器被清除时,您将不再泄漏内存。

将监听器注册到本地$scope ,而不是$rootScope , 监听器将在控制器被删除时自动销毁 。

所以要发表

 // EXAMPLE PUBLISHER angular.module('test').controller('CtrlPublish', ['$rootScope', '$scope', function ($rootScope, $scope) { $rootScope.$broadcast('topic', 'message'); }]); 

并订阅

 // EXAMPLE SUBSCRIBER angular.module('test').controller('ctrlSubscribe', ['$scope', function ($scope) { $scope.$on('topic', function (event, arg) { $scope.receiver = 'got your ' + arg; }); }]); 

Plunker

这是关于注销逻辑的源代码 。 你可以做:

 $rootScope.$on('action2@QuestionStatusController1', function () { $rootScope.$$listeners['action2@QuestionStatusController1'] = []; }) 

或者调用从$on()返回的注销函数

 var deregistration = $rootScope.$on('action2@QuestionStatusController1', function () { deregistration(); }) 
 $scope.$on('saveCancelLeadInfo', function (event, args) { if ($scope.$$listenerCount["saveCancelLeadInfo"] > 1) { $scope.$$listenerCount["saveCancelLeadInfo"] = 0; } });