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.