AngularJS: Clear $ watch

277

J'ai une fonction de surveillance dans mon application AngularJS.

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

Cependant, après une certaine condition (dans mon exemple, changer la page dans mon application d'une seule page ), je veux arrêter cette surveillance (comme pour effacer le délai d'expiration).

Comment puis je faire ça?

kamaci
la source

Réponses:

520

$watchrenvoie une fonction de désinscription. L'appeler annulerait l'enregistrement du $watcher.

var listener = $scope.$watch("quartz", function () {});
// ...
listener(); // Would clear the watch
Umur Kontacı
la source
24
Savez-vous si c'est une bonne pratique de désenregistrer tous vos auditeurs à la fin du cycle de vie d'un contrôleur (comme sur a $on('$destroy')) ou AngularJS s'en chargera? Merci!
yorch
81
Tous les observateurs seront supprimés lorsque la lunette sera détruite, vous n'avez pas besoin de les gérer
Umur Kontacı
6
Vous pouvez voir une discussion intéressante ici qui explique le problème: github.com/angular/angular.js/issues/4574 Fondamentalement, si vous affectez un écouteur au $ rootScope, vous devez le désaffecter vous-même, ou il persistera pendant $ changements de portée. Les observateurs sur $ scope sont détruits avec $ scope ($ scopes ne sont pas des singletons dans Angular, et ils sont créés et détruits si nécessaire).
Mladen Danic
3
Mais, que se passe-t-il si je veux seulement que l'observateur vérifie si la valeur existe, puis quand elle existe, effectuez quelques modifications, puis enregistrez-vous, j'ai déjà essayé - var listen = $ scope. $ Watch ('mvIdentity.currentUser', function (currentUser ) {test = 1; console.log ("->" + $ scope.updateemail + "-" + test); listen ();});
Harshit Laddha
4
@ UmurKontacı En fait, le commentaire de Deadman est parfaitement valable car votre commentaire d'origine n'est pas correct pour tous les cas.
GFoley83
49

scope. $ watch renvoie une fonction que vous pouvez appeler et qui désinscrira la montre.

Quelque chose comme:

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

setTimeout(function() {
    unbindWatch();
}, 1000);
Anders Ekdahl
la source
14
Oui, vous pouvez vous délier au sein de watchFn! Cas d'utilisation simple: vous souhaitez regarder et exécuter watchFn une seule fois, puis arrêter de regarder.
Mike Rapadas
3
Suis-je capable de relier la montre après avoir appelé la fonction de dissociation, comme si je la rappelais?
Bruno Finger
C'était utile. Faire le unbindWatch dans un délai d'attente semble important dans mes tests.
eeejay
Dans ce cas, vous devez utiliser $ timeout, que vous pouvez également désinscrire!
Ben Taliadoros
Mieux vaut éviter les temps morts
Davi Lima
25

Vous pouvez également effacer la montre à l'intérieur du rappel si vous souhaitez l'effacer juste après que quelque chose se soit produit. De cette façon, votre montre $ restera active jusqu'à son utilisation.

Ainsi...

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
la source
4

Quelque temps votre $ watch appelle dynamicallyet il va créer ses instances donc vous devez appeler la fonction de désenregistrement avant votre $watchfonction

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

Idéalement, chaque montre personnalisée doit être retirée lorsque vous quittez la lunette.

Il contribue à une meilleure gestion de la mémoire et à de meilleures performances des applications.

// 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
la source
4

Si vous avez trop d'observateurs et que vous devez tous les effacer, vous pouvez les pousser dans un tableau et les détruire tous $watchen boucle.

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
la source
-10

Pour supprimer la copie des observateurs, vous pouvez utiliser ceci:

watchers = void 0;
shailendra pathak
la source