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?

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

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);

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!
  } 
}

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 () {});

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
});

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

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.