AngularJS: очистить $ watch

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

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

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

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


person kamaci    schedule 19.02.2013    source источник


Ответы (6)


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

var listener = $scope.$watch("quartz", function () {});
// ...
listener(); // Would clear the watch
person Umur Kontacı    schedule 19.02.2013
comment
Знаете ли вы, является ли хорошей практикой отменить регистрацию всех ваших слушателей в конце жизненного цикла контроллера (например, на $on('$destroy')) или AngularJS позаботится о них? Благодарность! - person yorch; 02.10.2013
comment
Все наблюдатели будут удалены, когда прицел будет уничтожен, вам не нужно управлять ими. - person Umur Kontacı; 03.10.2013
comment
@ UmurKontacı - есть ли у вас источник для вашего утверждения о том, что при уничтожении прицела наблюдатели удаляются? Похоже, он не является частью _ функция - person jelinson; 16.02.2014
comment
Здесь вы можете увидеть интересное обсуждение, которое объясняет этот вопрос: github.com/angular/angular. js / issues / 4574 По сути, если вы назначаете слушателя для $ rootScope, вы должны отменить его назначение самостоятельно, иначе он будет сохраняться при изменении $ scope. Наблюдатели в $ scope уничтожаются с помощью $ scope ($ scopes не являются одиночными в Angular, и они создаются и уничтожаются по мере необходимости). - person Mladen Danic; 12.03.2014
comment
Но что, если я хочу, чтобы наблюдатель только проверял, существует ли значение, а затем, когда оно существует, внесите некоторые изменения, а затем отмените регистрацию, которую я уже пробовал - var listen = $ scope. $ Watch ('mvIdentity.currentUser', function (currentUser ) {test = 1; console.log (- ›+ $ scope.updateemail + - + test); listen ();}); - person Harshit Laddha; 22.06.2014
comment
@ UmurKontacı На самом деле комментарий мертвеца совершенно верен, так как ваш исходный комментарий не подходит для каждого случая. - person GFoley83; 22.07.2014
comment
Примечание. $ Scope. $$ watchers содержит все часы в определенной области. Это опасно, но ими можно манипулировать. Предоставлено: coderwall.com/p/d_aisq. - person Sanket Sahu; 02.10.2014
comment
Примечание: $scope.$$watchersCount очень помогает при отладке. - person Ice-Blaze; 04.11.2015

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

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

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

setTimeout(function() {
    unbindWatch();
}, 1000);
person Anders Ekdahl    schedule 19.02.2013
comment
Да, в watchFn можно отвязать! Простой вариант использования: вы хотите просмотреть и выполнить watchFn только один раз, а затем прекратить просмотр. - person Mike Rapadas; 04.01.2015
comment
Могу ли я повторно привязать часы после вызова функции отмены привязки, например, снова вызвать ее? - person Bruno Finger; 12.11.2015
comment
Это было полезно. Выполнение unbindWatch по таймауту кажется важным в моем тестировании. - person eeejay; 21.11.2015
comment
В этом случае вы должны использовать $ timeout, регистрацию которого также можно отменить! - person Ben Taliadoros; 08.09.2016
comment
Лучше избегать тайм-аутов - person Davi Lima; 07.06.2017

Вы также можете очистить часы внутри обратного вызова, если хотите очистить их сразу после того, как что-то произойдет. Таким образом, ваши $ 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!
  } 
}
person SoEzPz    schedule 23.07.2015

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

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

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

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

// 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
});
person Manish Kumar    schedule 19.09.2017

Если у вас слишком много наблюдателей и вам нужно очистить их все, вы можете поместить их в массив и уничтожить каждый $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 = [];
person Rewar    schedule 31.08.2016