AngularJS: Clear $ watch

277

Tengo una función de reloj en mi aplicación AngularJS.

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

Sin embargo, después de alguna condición (en mi ejemplo, cambiar la página en mi aplicación de una sola página ) quiero detener ese reloj (como borrar el tiempo de espera).

¿Cómo puedo hacer eso?

kamaci
fuente

Respuestas:

520

$watchdevuelve una función de desregistro. Llamarlo daría de baja el $watcher.

var listener = $scope.$watch("quartz", function () {});
// ...
listener(); // Would clear the watch
Umur Kontacı
fuente
24
¿Sabe si es una buena práctica cancelar el registro de todos sus oyentes al final del ciclo de vida del controlador (como en un $on('$destroy')) o AngularJS se encargará de ellos? ¡Gracias!
Yorch
81
Todos los observadores serán eliminados cuando se destruya el alcance, no es necesario administrarlos
Umur Kontacı
66
Puede ver una discusión interesante aquí que explica el asunto: github.com/angular/angular.js/issues/4574 Básicamente, si asigna un oyente al $ rootScope, debe desasignarlo usted mismo, o persistirá $ cambios de alcance. Los observadores en $ scope se destruyen con el $ scope ($ scopes no son singletons en Angular, y se crean y destruyen cuando es necesario).
Mladen Danic
3
Pero, ¿qué pasa si solo quiero que el observador verifique si el valor existe y luego, cuando existe, haga algunos cambios y luego me registre, ya lo intenté? Var listen = $ scope. $ Watch ('mvIdentity.currentUser', function (currentUser ) {prueba = 1; consola.log ("->" + $ scope.updateemail + "-" + prueba); listen ();});
Harshit Laddha
44
@ UmurKontacı En realidad, el comentario de deadman es perfectamente válido ya que su comentario original no es correcto para todos los casos.
GFoley83
49

scope. $ watch devuelve una función que puede llamar y que anulará el registro del reloj.

Algo como:

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

setTimeout(function() {
    unbindWatch();
}, 1000);
Anders Ekdahl
fuente
14
Sí, puedes relajarte dentro de watchFn! Caso de uso simple: desea mirar y ejecutar watchFn solo una vez, luego dejar de mirar.
Mike Rapadas
3
¿Puedo volver a vincular el reloj después de llamar a la función de desvinculación, como volver a llamarlo?
Bruno Finger
Esto fue útil. Hacer unbindWatch en un tiempo de espera parece importante en mis pruebas.
eeejay
En este caso, debe usar $ timeout, que también puede cancelar su registro.
Ben Taliadoros
Lo mejor es evitar los tiempos de espera
Davi Lima
25

También puede borrar el reloj dentro de la devolución de llamada si desea borrarlo justo después de que ocurra algo. De esa manera, su $ watch permanecerá activo hasta que se use.

Al igual que...

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
fuente
4

En algún momento su $ watch está llamando dynamicallyy creará sus instancias, por lo que debe llamar a la función de desregistro antes de su $watchfunción

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

Idealmente, cada reloj personalizado debe eliminarse cuando abandone el alcance.

Ayuda en una mejor gestión de la memoria y un mejor rendimiento de la aplicación.

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

Si tiene demasiados observadores y necesita eliminarlos a todos, puede insertarlos en una matriz y destruirlos $watchen un bucle.

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
fuente
-10

Para descartar la copia de los observadores, puede usar esto:

watchers = void 0;
Shailendra Pathak
fuente