AngularJS: Clear $ watch

277

Eu tenho uma função de relógio no meu aplicativo AngularJS.

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

No entanto, após alguma condição (no meu exemplo, alterar a página no meu aplicativo de página única) ), desejo interromper o relógio (como limpar o tempo limite).

Como eu posso fazer isso?

kamaci
fonte

Respostas:

520

$watchretorna uma função de cancelamento de registro. Chamá-lo cancelaria o registro de $watcher.

var listener = $scope.$watch("quartz", function () {});
// ...
listener(); // Would clear the watch
Umur Kontacı
fonte
24
Você sabe se é uma boa prática cancelar o registro de todos os seus ouvintes no final de um ciclo de vida do controlador (como em a $on('$destroy')) ou o AngularJS cuidará deles? obrigado!
yorch
81
Todos os observadores serão removidos quando o escopo for destruído. Você não precisará gerenciá-los
Umur Kontacı
6
Você pode ver uma discussão interessante aqui, que explica o assunto: github.com/angular/angular.js/issues/4574 Basicamente, se você atribuir um ouvinte ao $ rootScope, precisará desassociá-lo, ou ele persistirá. $ mudanças de escopo. Observadores no $ scope são destruídos com o $ scope ($ scope não são singletons no Angular e são criados e destruídos quando necessário).
Mladen Danic
3
Mas, e se eu quiser apenas o inspetor para verificar se o valor existe e, quando ele existir, fazer algumas alterações e depois se registrar, eu já tentei - var listen = $ scope. $ Watch ('mvIdentity.currentUser', function (currentUser ) {test = 1; console.log ("->" + $ scope.updateemail + "-" + test); listen ();});
Harshit Laddha
4
@ UmurKontacı O comentário de deadman é perfeitamente válido, pois seu comentário original não é correto para todos os casos.
precisa saber é o seguinte
49

$ watch retorna uma função que você pode chamar e que cancelará o registro do relógio.

Algo como:

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

setTimeout(function() {
    unbindWatch();
}, 1000);
Anders Ekdahl
fonte
14
Sim, você pode se desdobrar no watchFn! Caso de uso simples: você deseja assistir e executar o watchFn apenas uma vez e depois parar de assistir.
Mike Rapadas
3
Posso reativar o relógio depois de chamar a função de desbloqueio, como chamá-lo novamente?
Bruno Finger
Isso foi útil. Fazer o unbindWatch em um tempo limite parece importante nos meus testes.
eeejay
Nesse caso, você deve usar $ timeout, que também pode ser cancelado!
Ben Taliadoros
Melhor para o tempo limite Evitar
Davi Lima
25

Você também pode limpar o relógio dentro do retorno de chamada se quiser limpá-lo logo após algo acontecer. Dessa forma, seu $ watch permanecerá ativo até ser usado.

Igual a...

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!
  } 
}
SoEzPz
fonte
4

Algum tempo o seu $ watch está chamando dynamicallye ele cria suas instâncias para que você precise chamar a função de cancelamento de registro antes da sua $watchfunção

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

Idealmente, todo relógio personalizado deve ser removido quando você sair do escopo.

Ajuda no melhor gerenciamento de memória e no melhor desempenho do aplicativo.

// 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
});
Manish Kumar
fonte
4

Se você tiver muitos observadores e precisar limpá-los, poderá inseri-los em uma matriz e destruir todos os $watchem um loop.

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 = [];
Rewar
fonte
-10

Para descartar a cópia dos observadores, você pode usar o seguinte:

watchers = void 0;
shailendra pathak
fonte