tutorial ejemplos descargar javascript angularjs

javascript - ejemplos - $ scope. $ watch no se activa con cada cambio



angularjs tutorial (5)

Esto sucede porque el reloj solo se activará si el valor se cambia "entre" los bucles de resumen.

Su función está cambiando el valor del mensaje en el alcance en la misma función. Esto se ejecutará en el mismo bucle de resumen. Cuando angular se mueve al siguiente bucle, solo verá el último valor cambiado, que en su caso será hi22 .

Here''s un gran artículo que aclara este comportamiento.

Estoy usando angularJS 1.4.8, ayer noté que el $ scope. $ Watch no se activa en cada cambio que causó un error en mi aplicación.

¿Hay una manera de forzarlo a trabajar en cada cambio inmediatamente? Al igual que en este código, en cada cambio en el mensaje quiero que se active la función en reloj:

(function(){ angular.module(''myApp'', []) .controller(''myAppController'', myAppController) function myAppController($scope){ console.log(''controller loading !''); $scope.message = ''message1''; $scope.$watch(''message'', function(newMessage){ console.log(''newMessage'', newMessage) }); function changeMessage(){ $scope.message=''hi''; $scope.message=''hi12''; } changeMessage(); } })();

La consola imprimirá:

controller loading ! newMessage hi22

enlace Plunker https://plnkr.co/edit/SA1AcIVwr04uIUQFixAO?p=preview

edición: realmente me gustaría saber si hay alguna otra forma que no sea ajustar el cambio con el tiempo de espera y usar el ámbito de aplicación, en mi código original iv''e varios lugares donde cambio la propiedad del alcance y me gustaría evitar usar esto cada cambio .


No es necesario envolver changeMessage en setTimeout y $ apply al mismo tiempo. Si necesita saltarse algún tiempo antes de la ejecución, solo use:

function changeMessage(){ $timeout(function(){ $scope.message = ''message''; }/* or add time here, doesn''t matter */); }

O solo:

function changeMessage(){ $scope.message = ''message''; $scope.$apply(); }

Ambos métodos llaman $rootScope.$digest al final. Aquí hay más información: codingeek.com/angularjs/…


Si cambia el valor en el mismo ciclo de resumen, el observador no se activa y se toma el último valor. Cuando ejecutamos $timeout , $scope.message valor de $scope.message en el siguiente ciclo de resumen y el observador lo $scope.message como se espera.

Echa un vistazo a la prueba simple:

$scope.$watch(function(){ console.log(''trigger''); return $scope.message; }, function(newMessage){ console.log(''newMessage'', newMessage) }); function changeMessage(){ $scope.message=''hi''; $timeout(function(){ $scope.message=''hi12''; }); }

Salida:

controller loading ! trigger newMessage hi trigger trigger newMessage hi12 trigger


actualice la función changeMessage para que use $ scope. $ apply, que garantizará que sus cambios se reflejen y que Angular esté al tanto de sus cambios en la variable.

changeMessage() { setTimeout(function () { $scope.$apply(function () { $scope.message = "Timeout called!"; }); }, 2000); }


$watch() solo activa entre cada $digest() .

Explicación detallada sobre el $apply() y $digest()

En su caso, sigue actualizando el $scope.message en el ciclo $digest() actual.

Puede cambiar eso aplicando cada nuevo valor al $scope usando $apply() . Como escribió @Ajinkya. El único problema, con la configuración de 2000ms como tiempo de espera, no siempre garantiza que se ejecute después del $digest() . Además de eso, Angular tiene una función de tiempo de espera de compilación. Vea abajo.

(function(){ angular.module(''myApp'', []) .controller(''myAppController'', myAppController) function myAppController($scope, $timeout){ console.log(''controller loading !''); $scope.message = ''message1''; $scope.$watch(''message'', function(newMessage){ console.log(''newMessage'', newMessage) }); function changeMessage(){ setTimeout(function () { $scope.$apply(function () { $scope.message=''hi12''; }); }, 2000); } changeMessage(); } })();

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> <div ng-app="myApp" ng-controller="myAppController"></div>

Solución

La mejor manera sería llamar a la función build in $timeout , sin configurar el tiempo en milisegundos.

De esta manera, angular siempre garantiza que el $timeout se ejecute después del último $digest() . Además de eso. No tiene que usar $scope.$apply() . Debido a que $timeout allready ejecuta $digest() , donde $scope.$apply() $diggest() invoca manualmente un nuevo $diggest() .

(function(){ angular.module(''myApp'', []) .controller(''myAppController'', myAppController) function myAppController($scope, $timeout){ console.log(''controller loading !''); $scope.message = ''message1''; $scope.$watch(''message'', function(newMessage){ console.log(''newMessage'', newMessage) }); function changeMessage(){ $timeout(function () { $scope.message=''hi12''; }); } changeMessage(); } })();

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> <div ng-app="myApp" ng-controller="myAppController"></div>