Debe saber cómo funciona AngularJS para comprenderlo.
Ciclo de resumen y $ scope
En primer lugar, AngularJS define un concepto del llamado ciclo de digestión . Este ciclo puede considerarse como un ciclo, durante el cual AngularJS verifica si hay algún cambio en todas las variables observadas por todos los $scope
s. Entonces, si ha $scope.myVar
definido en su controlador y esta variable fue marcada para ser observada , entonces está indicando implícitamente a AngularJS que monitoree los cambios myVar
en cada iteración del ciclo.
Una pregunta de seguimiento natural sería: ¿Está todo relacionado con $scope
ser observado? Afortunadamente no. Si observa los cambios en cada objeto en su $scope
, entonces un ciclo de resumen tardaría años en evaluarse y rápidamente tendría problemas de rendimiento. Es por eso que el equipo de AngularJS nos dio dos formas de declarar algunas $scope
variables como observadas (lea a continuación).
$ watch ayuda a escuchar los cambios de $ alcance
Hay dos formas de declarar una $scope
variable como observada.
- Al usarlo en su plantilla a través de la expresión
<span>{{myVar}}</span>
- Al agregarlo manualmente a través del
$watch
servicio
Anuncio 1) Este es el escenario más común y estoy seguro de que lo has visto antes, pero no sabías que esto ha creado un reloj en segundo plano. Sí, lo hizo! El uso de directivas AngularJS (como ng-repeat
) también puede crear relojes implícitos.
Anuncio 2) Así es como creas tus propios relojes . $watch
El servicio le ayuda a ejecutar algún código cuando algún valor adjunto al $scope
ha cambiado. Raramente se usa, pero a veces es útil. Por ejemplo, si desea ejecutar algún código cada vez que cambia 'myVar', puede hacer lo siguiente:
function MyController($scope) {
$scope.myVar = 1;
$scope.$watch('myVar', function() {
alert('hey, myVar has changed!');
});
$scope.buttonClicked = function() {
$scope.myVar = 2; // This will trigger $watch expression to kick in
};
}
$ apply permite integrar cambios con el ciclo de resumen
Puede pensar en la $apply
función como un mecanismo de integración . Verá, cada vez que cambia alguna variable observada$scope
directamente al objeto, AngularJS sabrá que el cambio ha sucedido. Esto se debe a que AngularJS ya sabía monitorear esos cambios. Entonces, si sucede en el código administrado por el marco, el ciclo de resumen continuará.
Sin embargo, a veces desea cambiar algún valor fuera del mundo AngularJS y ver que los cambios se propagan normalmente. Considere esto: tiene un $scope.myVar
valor que se modificará dentro de un $.ajax()
controlador jQuery . Esto sucederá en algún momento en el futuro. AngularJS no puede esperar a que esto suceda, ya que no se le ha ordenado que espere en jQuery.
Para hacer frente a esto, $apply
se ha introducido. Le permite comenzar el ciclo de digestión explícitamente. Sin embargo, solo debe usar esto para migrar algunos datos a AngularJS (integración con otros marcos), pero nunca use este método combinado con el código regular de AngularJS, ya que AngularJS arrojará un error en ese momento.
¿Cómo se relaciona todo esto con el DOM?
Bueno, realmente deberías seguir el tutorial nuevamente, ahora que sabes todo esto. El ciclo de resumen asegurará que la IU y el código JavaScript permanezcan sincronizados, evaluando cada observador conectado a todos $scope
los mensajes mientras no cambie nada. Si no se producen más cambios en el ciclo de resumen, se considera que está terminado.
Puede adjuntar objetos al $scope
objeto explícitamente en el Controlador o declarándolos en {{expression}}
forma directamente en la vista.
Espero que eso ayude a aclarar algunos conocimientos básicos sobre todo esto.
Lecturas adicionales:
En AngularJS, actualizamos nuestros modelos, y nuestras vistas / plantillas actualizan el DOM "automáticamente" (a través de directivas integradas o personalizadas).
$ apply y $ watch, ambos métodos de alcance, no están relacionados con el DOM.
La página Conceptos (sección "Tiempo de ejecución") tiene una explicación bastante buena del bucle $ digest, $ apply, la cola $ evalAsync y la lista $ watch. Aquí está la imagen que acompaña al texto:
Cualquier código que tenga acceso a un alcance, normalmente controladores y directivas (sus funciones de enlace y / o sus controladores), puede configurar una " watchExpression " que AngularJS evaluará en relación con ese alcance. Esta evaluación ocurre cada vez que AngularJS ingresa a su bucle $ digest (en particular, el bucle "$ watch list"). Puede ver propiedades de ámbito individuales, puede definir una función para ver dos propiedades juntas, puede ver la longitud de una matriz, etc.
Cuando las cosas suceden "dentro de AngularJS", por ejemplo, escribe en un cuadro de texto que tiene habilitado el enlace de datos bidireccional de AngularJS (es decir, usa ng-model), un $ http callback dispara, etc. - $ apply ya se ha llamado, por lo que estás dentro del rectángulo "AngularJS" en la figura de arriba. Se evaluarán todas las watchExpressions (posiblemente más de una vez, hasta que no se detecten más cambios).
Cuando las cosas suceden "fuera de AngularJS", por ejemplo, usaste bind () en una directiva y luego ese evento se dispara, lo que resulta en que se llame tu devolución de llamada, o algunos incendios de devolución de llamada registrados por jQuery, todavía estamos en el rectángulo "Nativo". Si el código de devolución de llamada modifica cualquier cosa que $ watch está viendo, llame a $ apply para ingresar al rectángulo AngularJS, haciendo que se ejecute el bucle $ digest y, por lo tanto, AngularJS notará el cambio y hará su magia.
fuente
scope.$apply(scope.model)
, no entiendo qué datos se transfieren y cómo se transfieren al lugar correcto en el modelo.scope.$apply(scope.model)
simplemente se evaluaráscope.model
como una expresión angular y luego ingresará un bucle $ digest. En el artículo al que hace referencia, probablementescope.$apply()
sería suficiente, ya que el modelo ya está siendo $ vigilado. La función stop () está actualizando el modelo (creo que toUpdate es una referencia a scope.model), y luego se llama a $ apply.$watch
en la página, y el segundo enlace está roto, a partir de ahora, de todos modos). Dolorosamente, las versiones de archivo no almacenaron en caché el proceso asíncrono que creó el contenido.AngularJS extiende este bucle de eventos , creando algo llamado
AngularJS context
.$ watch ()
Cada vez que vincula algo en la interfaz de usuario, inserta un
$watch
en una$watch
lista .Aquí tenemos
$scope.user
, que está vinculado a la primera entrada, y tenemos$scope.pass
, que está vinculado a la segunda. Al hacer esto, agregamos dos$watch
es a la$watch
lista .Cuando se carga nuestra plantilla , AKA en la fase de vinculación, el compilador buscará todas las directivas y creará todos los
$watch
es necesarios.AngularJS proporciona
$watch
,$watchcollection
y$watch(true)
. A continuación se muestra un diagrama ordenado que explica en profundidad los tres tomados de los observadores .http://jsfiddle.net/2Lyn0Lkb/
$digest
lazoCuando el navegador recibe un evento que puede ser manejado por el contexto AngularJS
$digest
, se activará el bucle. Este bucle está hecho de dos bucles más pequeños. Uno procesa la$evalAsync
cola y el otro procesa el$watch list
. El$digest
recorrerá la lista de lo$watch
que tenemosAquí solo tenemos uno
$watch
porque ng-click no crea ningún reloj.Presionamos el botón.
$digest
bucle se ejecutará y solicitará cambios a cada $ watch.$watch
que el que estaba buscando cambios en $ scope.name informa un cambio, forzará otro$digest
ciclo.$digest
ciclo. Eso significa que cada vez que escribimos una carta en una entrada, el bucle se ejecutará comprobando$watch
en cada página.$ apply ()
Si llama
$apply
cuando se dispara un evento, pasará por el contexto angular, pero si no lo llama, se ejecutará fuera de él. Es tan fácil como eso.$apply
llamará al$digest()
bucle internamente e iterará sobre todos los relojes para garantizar que el DOM se actualice con el valor recién actualizado.El
$apply()
método activará observadores en toda la$scope
cadena, mientras que el$digest()
método solo activará observadores en la corriente$scope
y su corrientechildren
. Cuando ninguno de los$scope
objetos superiores necesita saber acerca de los cambios locales, puede usar$digest()
.fuente
Me pareció muy vídeos en profundidad que cubren
$watch
,$apply
,$digest
y digerir los ciclos de:AngularJS: comprensión de Watcher, $ watch, $ watchGroup, $ watchCollection, ng-change
AngularJS: comprensión del ciclo de resumen (fase de resumen o proceso de resumen o bucle de resumen)
Tutorial de AngularJS: comprensión de $ apply y $ digest (en profundidad)
A continuación hay un par de diapositivas utilizadas en esos videos para explicar los conceptos (por si acaso, si los enlaces anteriores se eliminan / no funcionan).
En la imagen de arriba, "$ scope.c" no se está viendo ya que no se usa en ninguno de los enlaces de datos (en el marcado). Los otros dos (
$scope.a
y$scope.b
) serán observados.De la imagen de arriba: Basado en el evento del navegador respectivo, AngularJS captura el evento, realiza un ciclo de resumen (revisa todos los relojes para detectar cambios), ejecuta funciones de reloj y actualiza el DOM. Si no eventos del navegador, el ciclo de digestión se pueden accionar manualmente usando
$apply
o$digest
.Más sobre
$apply
y$digest
:fuente
Hay
$watchGroup
y$watchCollection
también. Específicamente,$watchGroup
es realmente útil si desea llamar a una función para actualizar un objeto que tiene múltiples propiedades en una vista que no es un objeto dom, por ejemplo, otra vista en lienzo, WebGL o solicitud del servidor.Aquí, el enlace de documentación .
fuente
$watchCollection
pero veo que ya lo hiciste. Aquí hay documentación al respecto del sitio AngularJS. Proporcionan una muy buena visual de la$watch
profundidad. Tenga en cuenta que la información está cerca de la parte inferior de la página.Simplemente termine de leer TODO lo anterior, aburrido y con sueño (lo siento, pero es cierto). Muy técnico, profundo, detallado y seco. ¿Por qué estoy escribiendo? Debido a que AngularJS es masivo, muchos conceptos interconectados pueden volver loco a cualquiera. A menudo me preguntaba, ¿no soy lo suficientemente inteligente como para entenderlos? ¡No! ¡Es porque muy pocos pueden explicar la tecnología en un lenguaje para tontos sin todas las terminologías! Ok, déjame intentarlo:
1) Todas son cosas impulsadas por eventos. (Escucho la risa, pero sigue leyendo)
Si no sabe qué es el evento, entonces piense que coloca un botón en la página, conéctelo con una función usando "on-click", esperando que los usuarios hagan clic en él para activar las acciones que planta dentro del función. O piense en el "disparador" de SQL Server / Oracle.
2) $ watch es "al hacer clic".
Lo especial es que toma 2 funciones como parámetros, la primera da el valor del evento, la segunda toma el valor en consideración ...
3) $ digest es el jefe que revisa incansablemente , bla-bla-bla pero un buen jefe.
4) $ apply le brinda el camino cuando desea hacerlo manualmente , como a prueba de fallas (en caso de que el clic no se active, lo obliga a ejecutarse).
En un restaurante,
- camareros
se supone que deben tomar pedidos de clientes, esto es
- GERENTE corriendo para asegurarse de que todos los camareros estén despiertos, atentos a cualquier signo de cambios de los clientes. Esto es
$digest()
- EL PROPIETARIO tiene el máximo poder para conducir a todos a pedido, esto es
$apply()
fuente