如何在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.$rootScope.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; } });