AngularJS: Clear $ watch


277

Ho una funzione orologio nella mia applicazione AngularJS.

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

Tuttavia, dopo alcune condizioni (nel mio esempio, cambiare la pagina nella mia applicazione a pagina singola ) voglio fermare quell'orologio (come come cancellare il timeout).

Come lo posso fare?

Risposte:


520

$watchrestituisce una funzione di cancellazione. Chiamandolo si cancellerebbe il $watcher.

var listener = $scope.$watch("quartz", function () {});
// ...
listener(); // Would clear the watch

24
Sai se è una buona pratica annullare la registrazione di tutti i tuoi ascoltatori alla fine del ciclo di vita di un controller (come su un $on('$destroy')) o se AngularJS si prenderà cura di loro? Grazie!
yorch

81
Tutti gli osservatori verranno rimossi quando l'ambito viene distrutto, non è necessario gestirli
Umur Kontacı

6
Puoi vedere una discussione interessante qui che spiega la questione: github.com/angular/angular.js/issues/4574 Fondamentalmente, se assegni un ascoltatore a $ rootScope, devi disassegnartelo da solo, o persisterà attraverso $ scope change. Gli osservatori su $ scope vengono distrutti con $ scope ($ scopes non sono singoli in Angolare e vengono creati e distrutti quando necessario).
Mladen Danic,

3
Ma cosa succede se voglio solo che l'osservatore controlli se il valore esiste e poi quando esiste faccio alcune modifiche e poi de-registrarsi ho già provato - var hear = $ scope. $ Watch ('mvIdentity.currentUser', function (currentUser ) {test = 1; console.log ("->" + $ scope.updateemail + "-" + test); hear ();});
Harshit Laddha,

4
@ UmurKontacı In realtà il commento di deadman è perfettamente valido poiché il tuo commento originale non è corretto per ogni caso.
GFoley83,

49

scope. $ watch restituisce una funzione che è possibile chiamare e che annullerà la registrazione dell'orologio.

Qualcosa di simile a:

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

setTimeout(function() {
    unbindWatch();
}, 1000);

14
Sì, puoi rilassarti all'interno di watchFn! Caso d'uso semplice: vuoi guardare ed eseguire watchFn solo una volta, quindi smetti di guardare.
Mike Rapadas,

3
Sono in grado di ricollegare l'orologio dopo aver chiamato la funzione di sblocco, come richiamarlo di nuovo?
Bruno Finger,

Questo è stato utile Fare il unbindWatch in un timeout sembra importante nei miei test.
eeejay,

In questo caso dovresti usare $ timeout, che puoi anche annullare la registrazione!
Ben Taliadoros,

Meglio evitare i timeout
Davi Lima,

25

Puoi anche cancellare l'orologio all'interno del callback se vuoi cancellarlo subito dopo che succede qualcosa. In questo modo il tuo $ watch rimarrà attivo fino all'utilizzo.

Così...

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

Qualche volta il tuo $ watch sta chiamando dynamicallye creerà le sue istanze, quindi devi chiamare la funzione di cancellazione prima della tua $watchfunzione

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

4

Idealmente, ogni orologio personalizzato dovrebbe essere rimosso quando si lascia l'ambito.

Aiuta a una migliore gestione della memoria e migliori prestazioni dell'app.

// 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

Se hai troppi osservatori e devi cancellarli tutti, puoi inserirli in un array e distruggerli tutti $watchin un ciclo.

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.