我有以下内容:
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
})
}]);
我的理解是我需要取消注册听取事件。有人可以告诉我如何编码/执行此操作吗?
答案 0 :(得分:149)
如果您没有取消注册该事件,您将收到内存泄漏,因为您传递给$on
的函数将无法清除(因为它的引用仍然存在)。更重要的是,任何在其范围内起作用引用的变量也将被泄露。如果在应用程序中多次创建/销毁控制器,这将导致您的函数被多次调用。幸运的是,AngularJS提供了一些有用的方法来避免内存泄漏和不必要的行为:
$on
方法返回一个函数,可以调用该函数取消注册事件监听器。您需要将取消注册功能保存为变量以供日后使用:var cleanUpFunc = $scope.$on('yourevent', ...);
请参阅$on
的文档:http://docs.angularjs.org/api/ng.$rootScope.Scope#$on
每当在Angular中清理一个作用域(即控制器被破坏)时,就会在该作用域上触发$destroy
事件。您可以注册$scope
的{{1}}活动,然后通过该活动致电$destroy
。
您可以将这两个有用的东西绑在一起,以便正确清理您的订阅。我把这个例子放在一起:http://plnkr.co/edit/HGK9W0VJGip6fhYQQBCg?p=preview。如果您注释掉行cleanUpFunc
,然后点击切换按钮并执行填充按钮几次,您会注意到我们的事件处理程序被多次调用,这是不太理想的。
现在,在完成所有这些后,为了使您的具体情况正常,只需将cleanUpFunc();
中的代码更改为以下内容:
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();
});
}]);
中的cleanUpFunc()
,$destroy
事件的事件监听器将被取消订阅,当您的控制器被清理时,您将不再泄漏内存。
答案 1 :(得分:41)
在删除控制器时,在本地$scope
上注册侦听器,而不是$rootScope
和listener will be destroyed automatically。
所以要发布
// 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;
});
}]);
答案 2 :(得分:15)
以下是关于注销逻辑的source code。你可以这样做:
$rootScope.$on('action2@QuestionStatusController1', function () {
$rootScope.$$listeners['action2@QuestionStatusController1'] = [];
})
或调用从$on()
var deregistration = $rootScope.$on('action2@QuestionStatusController1', function () {
deregistration();
})
答案 3 :(得分:0)
$scope.$on('saveCancelLeadInfo', function (event, args) {
if ($scope.$$listenerCount["saveCancelLeadInfo"] > 1) {
$scope.$$listenerCount["saveCancelLeadInfo"] = 0;
} });