angularjs - ng-src angular 5
Mira la variable y cámbiala. (5)
En AngularJS tengo una directiva que vigila una variable de alcance. Cuando la variable contiene ciertos datos, entonces necesito alterar esa variable un poco. El problema es que cuando cambio la variable, mi $watch
se activa de nuevo. Así que termino en un bucle continuo.
scope.$watch(''someVar'', function(newValue, oldValue) {
console.log(newValue);
scope.someVar = [Do something with someVar];
});
Esto sigue activando $watch
nuevamente, lo que tiene sentido. Pero necesito una manera de cambiar la variable observada. ¿Hay alguna forma de hacer esto?
Así es como funciona el control de la suciedad. Cada vez que algo cambia en $scope
Angular girará a través de todo lo que está adjunto al alcance y seguirá haciéndolo hasta que no haya más cambios.
Si desea hacer algo así, tendrá que asegurarse de que su función $watch
sea idempotente. Tendrá que mirar tanto newValue
como oldValue
y averiguar si ya ha aplicado los cambios a su variable en este bucle $digest
. Cómo puede hacer eso depende un poco de qué tipo de cambios le esté haciendo a someVar
.
En general, desafortunadamente no es una buena idea cambiar una variable observada en una función de vigilancia.
Cuando se observa una variable en busca de cambios usando $scope.$watch
, los controles angulares si la referencia ha cambiado. Si es así, entonces se ejecuta el controlador $watch
para actualizar la vista.
Si planea cambiar la variable de alcance dentro del controlador $ watch, se activará un bucle infinito de $ digest porque la referencia de la variable de alcance cambia cada vez que se llama.
El truco para sortear el problema del compendio infinito es conservar la referencia dentro de su controlador $watch
usando angular.copy ( docs ):
scope.$watch(''someVar'', function(newValue, oldValue) {
console.log(newValue);
var someVar = [Do something with someVar];
// angular copy will preserve the reference of $scope.someVar
// so it will not trigger another digest
angular.copy(someVar, $scope.someVar);
});
Nota: Este truco solo funciona para referencias de objetos. No funcionará con primitivos.
En general, no es una buena idea actualizar una variable $watched
dentro de su propio oyente $watch
. Sin embargo, a veces puede ser inevitable.
Puedes manejarlo usando una variable bool
$scope.someVarChanged = false;
scope.$watch(''someVar'', function(newValue, oldValue) {
console.log(newValue);
$scope.someVarChanged = !$scope.someVarChanged!;
if($scope.someVarChanged) {
scope.someVar = [Do something with someVar];
}
});
Uso interno de la función si la condición a evitar continúa para el bucle
scope.$watch(''someVar'', function(newValue, oldValue) {
if(newValue!==oldValue) {
console.log(newValue);
scope.someVar = [Do something with someVar];
}
});
sí puedes cancelarlo así
var wathcer = scope.$watch(''someVar'', function(newValue, oldValue) {
console.log(newValue);
scope.someVar = [Do something with someVar];
});
wathcer(); // clear the watch