Ответ 1
Если вы не отмените регистрацию события, вы получите утечку памяти, так как функция, которую вы передаете в $on
, не будет очищена (поскольку ссылка на нее все еще существует). Что еще более важно, любые переменные, которые ссылаются на ссылки в своей области, также будут пропущены. Это приведет к тому, что ваша функция будет вызвана несколько раз, если ваш контроллер будет создан/уничтожен несколько раз в приложении. К счастью, AngularJS предоставляет несколько полезных методов, чтобы избежать утечек памяти и нежелательного поведения:
-
Метод
$on
возвращает функцию, которая может быть вызвана для деинсталляции прослушивателя событий. Вы хотите сохранить свою функцию де-регистрации как переменную для последующего использования: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();
, а затем несколько раз нажмите кнопку переключения и сделайте что-нибудь, вы заметите, что наш обработчик событий вызывается несколько раз, что действительно не требуется.
Теперь, после всего, чтобы ваша конкретная ситуация вела себя правильно, просто измените свой код в QuestionsStatusController2
на следующее:
angular.module('test')
.controller('QuestionsStatusController2',
['$rootScope', '$scope', '$resource', '$state',
function ($rootScope, $scope, $resource, $state) {
var cleanUpFunc = $rootScope.$on('[email protected]', function {
//write your listener here
});
$scope.$on('$destroy', function() {
cleanUpFunc();
});
}]);
Вызвав cleanUpFunc()
в $destroy
, ваш прослушиватель событий для события [email protected]
будет не подписан и вы больше не будете пропускать память, когда ваш контроллер будет очищен.