Как я могу отменить регистрацию широковещательного события в rootscope в AngularJS?
У меня есть следующие:
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
})
}]);
Это мое понимание, что мне нужно отменить регистрацию событий. Может кто-нибудь сказать мне, как я мог бы код / сделать это?
4 ответа:
если вы не отмените регистрацию события, вы получите утечку памяти, так как функция, которую вы передаете
$on
не будет очищаться (поскольку ссылка на него все еще существует). Что еще более важно, любые переменные, которые ссылаются на функции в своей области, также будут пропущены. Это приведет к тому, что ваша функция будет вызываться несколько раз, если ваш контроллер будет создан/уничтожен несколько раз в приложении. К счастью, AngularJS предоставляет несколько полезных методов, чтобы избежать утечек памяти и нежелательных поведение:
The
$on
метод возвращает функцию, которая может быть вызвана для отмены регистрации прослушивателя событий. Вы захотите сохранить свою функцию дерегистрации в качестве переменной для последующего использования:var cleanUpFunc = $scope.$on('yourevent', ...);
смотрите документацию для$on
: http://docs.angularjs.org/api/ng.$rootScope. Scope#$onвсякий раз, когда область очищается в угловой (т. е. контроллер разрушается) a
$destroy
события в этой области. Вы можно зарегистрироваться на$scope
' s$destroy
событие и вызвать вашcleanUpFunc
от этого.вы можете связать эти две полезные вещи вместе, чтобы очистить ваши подписки правильно. Я собрал пример этого:http://plnkr.co/edit/HGK9W0VJGip6fhYQQBCg?p=preview. если вы закомментируете строку
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
, ваш прослушиватель событий для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; }); }]);
здесь исходный код о логике снятия с учета. Вы можете сделать:
$rootScope.$on('action2@QuestionStatusController1', function () { $rootScope.$$listeners['action2@QuestionStatusController1'] = []; })
или вызовите функцию отмены регистрации, возвращенную из
$on()
var deregistration = $rootScope.$on('action2@QuestionStatusController1', function () { deregistration(); })