Angular.js $destroy event - следует ли вручную отменить привязку?
Я пытаюсь выяснить, может ли база angular автоматически отвязывать наблюдения и события сферы видимости, связанные с $scope.$on(...)
или $scope.$watch(...)
, когда область действия уничтожена?
Предположим, что у меня есть следующий код:
$scope.$on('someEvents', handleSomeEvent);
$scope.$watch('someProperty', handleSomePropertyChange);
Нужно ли вручную отключать эти наблюдатели и события, когда в области событий запускается событие $destroy?
Ответы
Ответ 1
Согласно Angular документации по $scope
:
'$ destroy()' необходимо вызывать в области, когда требуется, чтобы область действия и ее дочерние области были окончательно отделены от родителя и, таким образом, перестали участвовать в обнаружении изменения модели и уведомлении слушателя, вызвав.
Также
Удаление также подразумевает, что текущая область имеет право на сбор мусора.
Итак, кажется, что при вызове $destroy()
все наблюдатели и слушатели удаляются, а объект, который представляет область видимости, становится eligible for garbage collection
.
Если мы посмотрим на destroy()
исходный код, мы увидим строку:
forEach(this.$$listenerCount, bind(null, decrementListenerCount, this));
который должен удалить всех слушателей.
Как упоминалось в @glepretre, это относится к наблюдателям и слушателям в контроллере. Одна и та же страница документа, указанная выше, говорит, что:
Обратите внимание, что в AngularJS также существует событие $destroy jQuery, которое может использоваться для очистки привязок DOM до удаления элемента из DOM.
Итак, если у вас есть конкретные слушатели в директивах, вы должны слушать событие $destroy
и выполнять необходимую очистку самостоятельно
Ответ 2
Если область действия находится в контроллере, angular отключите для вас. Кроме того, вы можете отвязать свое событие, вызвав возвращаемую функцию:
var myevent = $scope.$on('someEvents', handleSomeEvent);
myevent() ; // unbind the event
http://docs.angularjs.org/api/ng/function/angular.bind
Ответ 3
Как уже было сказано, Angular действительно позаботится о том, чтобы очищать вещи для вас, когда это возможно. Поэтому, если вы выполняете $scope.$on('someEvents', handleSomeEvent);
, как только область будет уничтожена (например, когда вы переходите на другую страницу/просмотр в своем приложении), событие автоматически удаляется.
Важно отметить, что $rootScope
, конечно, никогда не уничтожается, если вы не покинете свое приложение. Поэтому, если вы выполняете $rootScope.$on('someEvents', handleSomeEvent);
, вам может потребоваться удалить событие самостоятельно, в зависимости от того, где вы слушаете событие:
- если в
controller
или directive
, вам придется удалить его вручную, иначе каждый раз, когда вы создадите экземпляр controller
, будет добавлено новое событие, и поэтому handleSomeEvent
будет много раз называется
- если в
service
, вам не нужно удалять его вручную, так как службы всегда singleton
(обратите внимание, что в Angular service
, factory
,... все в конечном итоге являются то же самое)