AngularJS: Clear $ watch


277

У меня есть функция наблюдения в моем приложении AngularJS.

$scope.$watch('quartzCrystal', function () {
   ...
}

Однако после некоторого условия (в моем примере, изменения страницы в моем одностраничном приложении ) я хочу остановить это наблюдение (как очистка тайм-аута).

Как я могу это сделать?

Ответы:


520

$watchвозвращает функцию отмены регистрации. Вызов это сняло бы с учета $watcher.

var listener = $scope.$watch("quartz", function () {});
// ...
listener(); // Would clear the watch

24
Знаете ли вы, является ли хорошей практикой отмена регистрации всех ваших слушателей в конце жизненного цикла контроллера (как на a $on('$destroy')), или AngularJS позаботится о них? Спасибо!
Йорк

81
Все наблюдатели будут удалены, когда область будет уничтожена, вам не нужно управлять этим
Umur Kontacı

6
Вы можете увидеть интересную дискуссию, которая объясняет этот вопрос: github.com/angular/angular.js/issues/4574 По сути, если вы назначаете слушателя для $ rootScope, вы должны отменить его самостоятельно, или он будет сохраняться до $ меняется область. Наблюдатели за $ scope уничтожаются с помощью $ scope ($ scopes не являются синглетонами в Angular, и они создаются и уничтожаются при необходимости).
Младен Даник

3
Но что, если я хочу, чтобы наблюдатель только проверял, существует ли значение, а затем, когда он существует, вносит некоторые изменения, а затем регистрирует себя, я уже пробовал - var listen = $ scope. $ Watch ('mvIdentity.currentUser', function (currentUser) ) {test = 1; console.log ("->" + $ scope.updateemail + "-" + test); listen ();});
Харшит Ладдха

4
@ UmurKontacı На самом деле комментарий мертвеца совершенно действителен, так как ваш оригинальный комментарий не верен для каждого случая.
GFoley83

49

scope. $ watch возвращает функцию, которую вы можете вызвать и которая отменяет регистрацию часов.

Что-то вроде:

var unbindWatch = $scope.$watch("myvariable", function() {
    //...
});

setTimeout(function() {
    unbindWatch();
}, 1000);

14
Да, вы можете отменить привязку в watchFn! Простой вариант использования: вы хотите посмотреть и запустить watchFn только один раз, а затем прекратить просмотр.
Майк Рападас

3
Могу ли я перепривязать часы после вызова функции отмены привязки, например, при ее повторном вызове?
Бруно Фингер

Это было полезно. Выполнение unbindWatch за тайм-аут кажется важным в моем тестировании.
Eeejay

В этом случае вы должны использовать $ timeout, который вы также можете отменить!
Бен Талиадорос

Лучше всего избегать таймаутов
Дави Лима

25

Вы также можете очистить часы внутри обратного вызова, если хотите очистить их сразу после того, как что-то произойдет. Таким образом, ваши $ watch будут оставаться активными до использования.

Вот так...

var clearWatch = $scope.$watch('quartzCrystal', function( crystal ){
  if( isQuartz( crystal )){
    // do something special and then stop watching!
    clearWatch();
  }else{
    // maybe do something special but keep watching!
  } 
}

4

Некоторое время ваш $ watch вызывает, dynamicallyи он будет создавать свои экземпляры, поэтому вам придется вызывать функцию отмены регистрации перед вашей $watchфункцией.

if(myWatchFun)
  myWatchFun(); // it will destroy your previous $watch if any exist
myWatchFun = $scope.$watch("abc", function () {});

4

В идеале, все пользовательские часы должны быть удалены, когда вы покидаете область.

Это помогает улучшить управление памятью и повысить производительность приложений.

// call to $watch will return a de-register function
var listener = $scope.$watch(someVariableToWatch, function(....));

$scope.$on('$destroy', function() {
    listener(); // call the de-register function on scope destroy
});

4

Если у вас слишком много наблюдателей, и вам нужно очистить их все, вы можете поместить их в массив и уничтожить каждый $watchв цикле.

var watchers = [];
watchers.push( $scope.$watch('watch-xxx', function(newVal){
   //do something
}));    

for(var i = 0; i < watchers.length; ++i){
    if(typeof watchers[i] === 'function'){
        watchers[i]();
    }
}

watchers = [];

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.