¿Cómo funciona el enlace de datos en AngularJS?

¿Cómo funciona el enlace de datos en el AngularJS ¿marco de referencia?

No he encontrado detalles técnicos sobre su sitio. Está más o menos claro cómo funciona cuando los datos se propagan de una vista a otro. Pero, ¿cómo rastrea AngularJS los cambios de las propiedades del modelo sin establecedores y captadores?

Encontré que hay Observadores de JavaScript que puede hacer este trabajo. Pero no se admiten en Internet Explorer 6 y Internet Explorer 7. Entonces, ¿cómo sabe AngularJS que cambié, por ejemplo, lo siguiente y reflejé este cambio en una vista?

myobject.myproperty="new value";

preguntado el 13 de marzo de 12 a las 10:03

Tenga en cuenta que desde angular 1.0.0rc1 debe especificar ng-model-instant (docs-next.angularjs.org/api/…) para tener su moder actualizado locamente. De lo contrario, se actualizará en caso de desenfoque. -

El enlace de Marcello aparentemente está roto, así que aquí está de nuevo: github.com/mhevery/angular.js/blob/master/docs/content/guide/… -

@orian, ese enlace es malo. actualizado a (supongo) es el mismo - docs.angularjs.org/guide/databinding -

Para aquellos que todavía leen esta pregunta, tenga en cuenta que Angular 2.0 ha cambiado mucho la forma en que se vinculan los datos desde Angular 1.x para trabajar con componentes web y abordar muchos de los problemas en las respuestas a continuación. -

14 Respuestas

AngularJS recuerda el valor y lo compara con un valor anterior. Ésta es una verificación sucia básica. Si hay un cambio en el valor, dispara el evento de cambio.

La $apply() método, que es lo que llama cuando está haciendo la transición de un mundo que no es AngularJS a un mundo AngularJS, llama $digest(). Un resumen es simplemente un chequeo sucio. Funciona en todos los navegadores y es totalmente predecible.

Para contrastar la verificación sucia (AngularJS) frente a los oyentes de cambio (KnockoutJS y Backbone.js): Si bien la verificación sucia puede parecer simple e incluso ineficiente (lo abordaré más adelante), resulta que es semánticamente correcto todo el tiempo, mientras que los oyentes de cambios tienen muchos casos extraños y necesitan cosas como el seguimiento de dependencias para hacer es más semánticamente correcto. El seguimiento de dependencias de KnockoutJS es una característica inteligente para un problema que AngularJS no tiene.

Problemas con los oyentes de cambios:

  • La sintaxis es atroz, ya que los navegadores no la admiten de forma nativa. Sí, hay proxies, pero no son semánticamente correctos en todos los casos y, por supuesto, no hay proxies en los navegadores antiguos. La conclusión es que la verificación sucia le permite hacer POJO, mientras que KnockoutJS y Backbone.js te obligan a heredar de sus clases y acceder a tus datos a través de accesores.
  • Cambiar la coalescencia. Suponga que tiene una variedad de elementos. Supongamos que desea agregar elementos a una matriz, ya que está realizando un bucle para agregar, cada vez que agrega, está activando eventos en el cambio, que está representando la interfaz de usuario. Esto es muy malo para el rendimiento. Lo que desea es actualizar la interfaz de usuario solo una vez, al final. Los eventos de cambio son demasiado detallados.
  • Los oyentes de cambios disparan inmediatamente a un establecedor, lo cual es un problema, ya que el oyente de cambios puede cambiar aún más los datos, lo que dispara más eventos de cambio. Esto es malo ya que en su pila puede tener varios eventos de cambio sucediendo a la vez. Suponga que tiene dos matrices que deben mantenerse sincronizadas por cualquier motivo. Solo puede agregar a uno u otro, pero cada vez que agrega dispara un evento de cambio, que ahora tiene una visión inconsistente del mundo. Este es un problema muy similar al bloqueo de subprocesos, que JavaScript evita ya que cada devolución de llamada se ejecuta exclusivamente y hasta su finalización. Los eventos de cambio rompen esto, ya que los establecedores pueden tener consecuencias de gran alcance que no son intencionadas ni obvias, lo que crea el problema del hilo de nuevo. Resulta que lo que quiere hacer es retrasar la ejecución del oyente y garantizar que solo se ejecute un oyente a la vez, por lo tanto, cualquier código es libre de cambiar datos y sabe que no se ejecuta ningún otro código mientras lo hace. .

¿Qué pasa con el rendimiento?

Por lo tanto, puede parecer que somos lentos, ya que la verificación sucia es ineficaz. Aquí es donde debemos mirar los números reales en lugar de solo tener argumentos teóricos, pero primero definamos algunas restricciones.

Los humanos somos:

  • Lenta - Cualquier valor superior a 50 ms es imperceptible para los humanos y, por tanto, puede considerarse "instantáneo".

  • limitados - Realmente no se pueden mostrar más de 2000 piezas de información a un humano en una sola página. Cualquier cosa más que eso es una interfaz de usuario realmente mala, y los humanos no pueden procesar esto de todos modos.

Entonces, la verdadera pregunta es esta: ¿Cuántas comparaciones se pueden hacer en un navegador en 50 ms? Esta es una pregunta difícil de responder ya que entran en juego muchos factores, pero aquí hay un caso de prueba: http://jsperf.com/angularjs-digest/6 lo que crea 10,000 espectadores. En un navegador moderno, esto lleva algo menos de 6 ms. Sobre Internet Explorer 8 tarda unos 40 ms. Como puede ver, esto no es un problema, incluso en navegadores lentos en estos días. Hay una advertencia: las comparaciones deben ser simples para ajustarse al límite de tiempo ... Desafortunadamente, es demasiado fácil agregar una comparación lenta en AngularJS, por lo que es fácil crear aplicaciones lentas cuando no sabes lo que necesitas. estás haciendo. Pero esperamos tener una respuesta proporcionando un módulo de instrumentación, que le mostraría cuáles son las comparaciones lentas.

Resulta que los videojuegos y las GPU usan el enfoque de verificación sucia, específicamente porque es consistente. Siempre que superen la frecuencia de actualización del monitor (generalmente 50-60 Hz, o cada 16.6-20 ms), cualquier rendimiento por encima de eso es un desperdicio, por lo que es mejor dibujar más cosas que aumentar los FPS.

Respondido el 20 de diciembre de 15 a las 21:12

@Mark: sí, en KO solo agrega .extend ({throttle: 500}) para esperar 500 milisegundos después del último evento de cambio antes de actuar. - Daniel Earwicker

Toda esta respuesta es excelente, además de "Siempre que obtengan 50 fps, cualquier rendimiento por encima de eso es un desperdicio, ya que el ojo humano no puede apreciarlo, por lo que es mejor dibujar más cosas que aumentar los fps". Esa afirmación es completamente incorrecta según su aplicación. El ojo definitivamente puede apreciar más de 50 fps, y como muestran los diversos problemas con la realidad virtual (lea cualquiera de los últimos de John Carmack o Michael Abrash, especialmente la charla GDC 2013 VR de este último), 50 fps es en realidad demasiado lento. Aparte de eso, tu respuesta es genial. Simplemente no quiero que se difunda información errónea. - Nate Bundy

@DavidRivers us es µs como en utorrent 1µs = 0.000001s - Thorgeir

La afirmación podría decirse fácilmente al revés como "La comprobación sucia es una característica inteligente para un problema que no tiene el nocaut". ES6 utiliza observables y angular se deshace de las comprobaciones sucias. El mundo real se puso al día con esta respuesta y demostró que era falsa. - cónico

"Cualquier valor superior a 50 ms es imperceptible para los humanos" no es cierto. En las pruebas, hemos descubierto que nuestros clientes pueden distinguir fácilmente entre una latencia de actualización de 50 ms (20 fps) y una latencia de actualización de 16.6 ms (60 fps). Las escenas que se ejecutan a la velocidad anterior obtienen constantemente calificaciones más bajas de "cómo se sintió", incluso cuando las personas no registraron conscientemente la velocidad de fotogramas. - Crashworks

Misko ya dio una descripción excelente de cómo funcionan los enlaces de datos, pero me gustaría agregar mi opinión sobre el problema de rendimiento con el enlace de datos.

Como dijo Misko, alrededor de 2000 enlaces es donde comienza a ver problemas, pero de todos modos no debería tener más de 2000 piezas de información en una página. Esto puede ser cierto, pero no todos los enlaces de datos son visibles para el usuario. Una vez que comience a construir cualquier tipo de widget o cuadrícula de datos con enlace bidireccional, puede aun alcanzó 2000 enlaces, sin tener una mala experiencia de usuario.

Considere, por ejemplo, un cuadro combinado donde puede escribir texto para filtrar las opciones disponibles. Este tipo de control podría tener ~ 150 elementos y aún así ser altamente utilizable. Si tiene alguna característica adicional (por ejemplo, una clase específica en la opción seleccionada actualmente), comienza a obtener 3-5 enlaces por opción. Ponga tres de estos widgets en una página (por ejemplo, uno para seleccionar un país, el otro para seleccionar una ciudad en dicho país y el tercero para seleccionar un hotel) y ya estará entre 1000 y 2000 enlaces.

O considere una cuadrícula de datos en una aplicación web corporativa. 50 filas por página no es descabellado, cada una de las cuales podría tener de 10 a 20 columnas. Si crea esto con ng-repeats y / o tiene información en algunas celdas que usa algunos enlaces, podría estar acercándose a 2000 enlaces solo con esta cuadrícula.

Encuentro que esto es un enorme problema al trabajar con AngularJS, y la única solución que he podido encontrar hasta ahora es construir widgets sin usar enlaces bidireccionales, en lugar de usar ngOnce, anular el registro de observadores y trucos similares, o construir directivas que construyan el DOM con jQuery y manipulación DOM. Siento que esto frustra el propósito de usar Angular en primer lugar.

Me encantaría escuchar sugerencias sobre otras formas de manejar esto, pero tal vez debería escribir mi propia pregunta. Quería poner esto en un comentario, pero resultó ser demasiado largo para eso ...

TL; DR
El enlace de datos puede causar problemas de rendimiento en páginas complejas.

respondido 05 nov., 18:12

Sí, apoyo esto. La responsabilidad principal de nuestra aplicación es mostrar conexiones entre diferentes entidades. Una página determinada puede tener 10 secciones. Cada sección tiene una mesa. Cada tabla tiene 2-5 filtros de tipo anticipado. Cada tabla tiene 2-5 columnas, cada una con 10 filas. Muy rápidamente nos encontramos con problemas de rendimiento y vamos con las opciones de "trucos similares". - Scott Silvi

¿Es justo decir que Angular no se trata solo de vinculación de datos y que algunas aplicaciones pueden no querer usar esta función exactamente por las razones que otras han citado? Creo que el enfoque de DI y modularidad en sí mismo vale mucho; Tener un enlace automático mágico es bueno, pero en todas las implementaciones existentes hay compensaciones de rendimiento. El estilo de Angular es posiblemente superior para la mayoría de las aplicaciones web de CRUD, y la gente simplemente está chocando contra una pared al tratar de llevarlo a los extremos. Sería bueno tener un método alternativo de escucha de eventos compatible, pero ¿tal vez eso sea fundamentalmente demasiado complejo para un solo marco? - jason boyd

Angular ahora tiene un enlace de datos de una vía y una sola vez para ayudar con este problema. Además, ahora tiene índices para su fuente repetidora, lo que le permite modificar la lista sin reconstruir el dom para todo el contenido. - Gaute Loken

@MW. Honestamente, pensé que Bind-Once estaba en el núcleo. Pero parece que no lo es. Es algo que puedes hacer cuando escribes tus propias directivas, básicamente vinculando cosas sin mirarlas. Sin embargo, hay un mod ux para ello: github.com/pasvaz/bindonce - Gaute Loken

Un saludo desde el futuro para cualquiera que lea esto: el enlace único ahora es una característica central en Angular v1.3, lea más aquí: docs.angularjs.org/guide/expresión - Aurelio

Comprobando sucio el $scope objeto

Angular mantiene un simple array de observadores en el $scope objetos. Si inspecciona alguna $scope encontrará que contiene un array , que son $$watchers.

Cada observador es un object que contiene entre otras cosas

  1. Una expresión que el observador está monitoreando. Esto podría ser solo un attribute nombre, o algo más complicado.
  2. Un último valor conocido de la expresión. Esto se puede comparar con el valor calculado actual de la expresión. Si los valores difieren, el observador activará la función y marcará la $scope tan sucio.
  3. Una función que se ejecutará si el observador está sucio.

Cómo se definen los observadores

Hay muchas formas diferentes de definir un observador en AngularJS.

  • Puede explícitamente $watch an attribute on $scope.

      $scope.$watch('person.username', validateUnique);
    
  • Puedes colocar un {{}} interpolación en su plantilla (se creará un observador para usted en la $scope).

      <p>username: {{person.username}}</p>
    
  • Puede solicitar una directiva como ng-model para definir el observador por ti.

      <input ng-model="person.username" />
    

La $digest El ciclo compara a todos los observadores con su último valor.

Cuando interactuamos con AngularJS a través de los canales normales (ng-model, ng-repeat, etc.), la directiva activará un ciclo de resumen.

Un ciclo de digestión es un primer recorrido en profundidad de $scope y todos sus hijos. Para cada $scope object, iteramos sobre su $$watchers array y evaluar todas las expresiones. Si el nuevo valor de expresión es diferente del último valor conocido, se llama a la función del observador. Esta función podría volver a compilar parte del DOM, volver a calcular un valor en $scope, desencadenar un AJAX request, cualquier cosa que necesite que haga.

Cada ámbito se atraviesa y cada expresión de observación se evalúa y se compara con el último valor.

Si se activa un observador, el $scope es sucio

Si se activa un observador, la aplicación sabe que algo ha cambiado y el $scope está marcado como sucio.

Las funciones del observador pueden cambiar otros atributos en $scope o en un padre $scope. Si uno $watcher se ha activado la función, no podemos garantizar que nuestro otro $scopes todavía están limpios, por lo que ejecutamos todo el ciclo de digestión nuevamente.

Esto se debe a que AngularJS tiene un enlace bidireccional, por lo que los datos se pueden pasar de nuevo al $scope árbol. Podemos cambiar un valor en un mayor $scope que ya ha sido digerido. Quizás cambiemos un valor en el $rootScope.

Si $digest está sucio, ejecutamos todo $digest ciclo de nuevo

Continuamente recorremos el $digest ciclo hasta que el ciclo de digestión salga limpio (todos $watch las expresiones tienen el mismo valor que tenían en el ciclo anterior), o llegamos al límite de resumen. De forma predeterminada, este límite se establece en 10.

Si alcanzamos el límite de resumen, AngularJS generará un error en la consola:

10 $digest() iterations reached. Aborting!

El resumen es difícil para la máquina pero fácil para el desarrollador.

Como puede ver, cada vez que algo cambia en una aplicación AngularJS, AngularJS verificará a cada observador en el $scope jerarquía para ver cómo responder. Para un desarrollador, esto es una gran ayuda para la productividad, ya que ahora no necesita escribir casi ningún código de cableado, AngularJS solo notará si un valor ha cambiado y hará que el resto de la aplicación sea consistente con el cambio.

Sin embargo, desde la perspectiva de la máquina, esto es tremendamente ineficiente y ralentizará nuestra aplicación si creamos demasiados observadores. Misko ha citado una cifra de aproximadamente 4000 observadores antes de que su aplicación se sienta lenta en los navegadores más antiguos.

Este límite es fácil de alcanzar si ng-repeat sobre un gran JSON array por ejemplo. Puede mitigar esto utilizando características como el enlace único para compilar una plantilla sin crear observadores.

Cómo evitar crear demasiados observadores

Cada vez que su usuario interactúa con su aplicación, cada observador de su aplicación será evaluado al menos una vez. Una gran parte de la optimización de una aplicación AngularJS es reducir la cantidad de observadores en su $scope árbol. Una forma sencilla de hacerlo es con vinculante una vez.

Si tiene datos que rara vez cambiarán, puede vincularlos solo una vez usando la sintaxis ::, así:

<p>{{::person.username}}</p>

or

<p ng-bind="::person.username"></p>

El enlace solo se activará cuando se procese la plantilla que lo contiene y los datos se carguen en $scope.

Esto es especialmente importante cuando tiene un ng-repeat con muchos elementos.

<div ng-repeat="person in people track by username">
  {{::person.username}}
</div>

Respondido el 20 de junio de 20 a las 10:06

Gracias @ user2864740, aunque es correcto que la respuesta de Misko sea superior. Conoce el marco mejor que nadie, y es genial que se involucre con Stack Overflow .. - superluminario

No estoy de acuerdo con que dicha respuesta deba estar en la parte superior; Existe una diferencia entre saber algo y escribir una respuesta relevante / detallada para una pregunta específica. Hay mejores formas de obtener elogios. De todos modos .. - user2864740

No dudo que eso sea cierto, pero preguntas preguntas y respuestas respuestas :) - user2864740

Buena respuesta que cubre cómo se comporta el cheque sucio y qué está evaluando realmente, una cosa no estaba muy clara en la respuesta de Misko. - Strider

Excelente y detallada respuesta. @superluminary, gracias por tal respuesta. Además, después de leer esta respuesta, llego al punto de que no debemos agregar una expresión no idempotente como una expresión que se está observando. - Mangu Singh Rajpurohit

Este es mi entendimiento básico. ¡Bien puede estar mal!

  1. Los elementos se miran pasando una función (devolver lo que se va a ver) al $watch método.
  2. Los cambios en los elementos observados deben realizarse dentro de un bloque de código envuelto por el $apply método.
  3. Al final de la $apply La $digest Se invoca el método que pasa por cada uno de los relojes y comprueba si han cambiado desde la última vez que $digest corrió.
  4. Si se encuentran cambios, el resumen se invoca nuevamente hasta que todos los cambios se estabilicen.

En el desarrollo normal, la sintaxis de enlace de datos en el HTML le dice al compilador AngularJS que cree los relojes por usted y los métodos del controlador se ejecutan dentro $apply ya. Entonces, para el desarrollador de aplicaciones, todo es transparente.

Respondido el 06 de enero de 17 a las 08:01

¿Cuándo se activa el método de aplicación? - numan salati

@EliseuMonar El bucle de resumen se ejecuta como resultado de algún evento o llamar a $ apply (), no se llama periódicamente en función de un temporizador. ver ¿Cómo funciona la función $ watch de AngularJS? y ¿Cómo funciona el enlace y la digestión en AngularJS? - ADL

@remi, no me preocupa la última versión de AngularJS. ¿Ya están usando proxies u Object.observe? Si no es así, todavía se encuentran en la era de las comprobaciones sucias, que crea un ciclo cronometrado para ver si los atributos del modelo han cambiado. - Eliseu Monar dos Santos

He leído que el resumen se ejecutará un máximo de diez veces sitepoint.com/understanding-angulars-apply-digest - user137717

Yo mismo me pregunté esto por un tiempo. Sin setters, ¿cómo AngularJS notar cambios en el $scope ¿objeto? ¿Los encuesta?

Lo que realmente hace es esto: cualquier lugar "normal" en el que modifique el modelo ya fue llamado desde las entrañas de AngularJS, por lo que llama automáticamente $apply para usted después de que se ejecute su código. Digamos que su controlador tiene un método que está conectado a ng-click en algún elemento. Porque AngularJS conecta la llamada de ese método por usted, tiene la oportunidad de hacer una $apply en el lugar apropiado. Asimismo, para las expresiones que aparecen directamente en las vistas, esas son ejecutadas por AngularJS entonces lo hace el $apply.

Cuando la documentación habla de tener que llamar $apply manualmente para el código fuera de AngularJS, se trata de un código que, cuando se ejecuta, no proviene de AngularJS sí mismo en la pila de llamadas.

contestado el 06 de mayo de 18 a las 01:05

Explicando con imágenes:

El enlace de datos necesita un mapeo

La referencia en el alcance no es exactamente la referencia en la plantilla. Cuando vincula dos objetos, necesita un tercero que escuche al primero y modifique el otro.

enter image description here

Aquí, cuando modifica el <input>, tocas el datos-ref3. Y el mecanismo clásico de enlace de datos cambiará datos-ref4. Entonces, ¿cómo el otro {{data}} las expresiones se moverán?

Los eventos llevan a $ digest ()

enter image description here

Angular mantiene un oldValue y newValue de cada encuadernación. Y despues de cada Evento angular, el famoso $digest() bucle comprobará la lista de seguimiento para ver si algo ha cambiado. Estos Eventos angulares se encuentran las ng-click, ng-change, $http completado ... El $digest() se repetirá tanto como cualquier oldValue difiere de la newValue.

En la imagen anterior, notará que data-ref1 y data-ref2 han cambiado.

Conclusiones

Es un poco como el huevo y la gallina. Nunca se sabe quién comienza, pero es de esperar que funcione la mayor parte del tiempo como se esperaba.

El otro punto es que puede comprender fácilmente el impacto profundo de un enlace simple en la memoria y la CPU. Con suerte, las computadoras de escritorio son lo suficientemente gordas para manejar esto. Los teléfonos móviles no son tan fuertes.

Respondido el 16 de Septiembre de 17 a las 08:09

Obviamente, no hay una verificación periódica de Scope si hay algún cambio en los Objetos adjuntos. No se vigilan todos los objetos adjuntos al osciloscopio. El alcance prototípicamente mantiene un $$ vigilantes . Scope solo itera a través de esto $$watchers cuando $digest se llama .

Angular agrega un observador a los $$ observadores para cada uno de estos

  1. {{expresión}}: en tus plantillas (y en cualquier otro lugar donde haya una expresión) o cuando definimos ng-model.
  2. $ scope. $ watch ('expresión / función'): en su JavaScript, podemos simplemente adjuntar un objeto de alcance para que angular lo observe.

$ reloj La función toma tres parámetros:

  1. La primera es una función de observador que simplemente devuelve el objeto o simplemente podemos agregar una expresión.

  2. El segundo es una función de escucha que se llamará cuando haya un cambio en el objeto. Todas las cosas como los cambios de DOM se implementarán en esta función.

  3. El tercero es un parámetro opcional que toma un booleano. Si es cierto, angular deep observa el objeto y si su falso Angular solo hace una referencia al observar el objeto. La implementación aproximada de $ watch se ve así

Scope.prototype.$watch = function(watchFn, listenerFn) {
   var watcher = {
       watchFn: watchFn,
       listenerFn: listenerFn || function() { },
       last: initWatchVal  // initWatchVal is typically undefined
   };
   this.$$watchers.push(watcher); // pushing the Watcher Object to Watchers  
};

Hay algo interesante en Angular llamado Digest Cycle. El ciclo $ digest comienza como resultado de una llamada a $ scope. $ Digest (). Suponga que cambia un modelo $ scope en una función de controlador a través de la directiva ng-click. En ese caso, AngularJS activa automáticamente un ciclo de $ digest llamando a $ digest (). Además de ng-click, hay varias otras directivas / servicios incorporados que le permiten cambiar modelos (por ejemplo, ng-model, $ timeout, etc.) y activa automáticamente un ciclo de $ digest. La implementación aproximada de $ digest tiene este aspecto.

Scope.prototype.$digest = function() {
      var dirty;
      do {
          dirty = this.$$digestOnce();
      } while (dirty);
}
Scope.prototype.$$digestOnce = function() {
   var self = this;
   var newValue, oldValue, dirty;
   _.forEach(this.$$watchers, function(watcher) {
          newValue = watcher.watchFn(self);
          oldValue = watcher.last;   // It just remembers the last value for dirty checking
          if (newValue !== oldValue) { //Dirty checking of References 
   // For Deep checking the object , code of Value     
   // based checking of Object should be implemented here
             watcher.last = newValue;
             watcher.listenerFn(newValue,
                  (oldValue === initWatchVal ? newValue : oldValue),
                   self);
          dirty = true;
          }
     });
   return dirty;
 };

Si usamos JavaScript setTimeout () función para actualizar un modelo de alcance, Angular no tiene forma de saber qué podría cambiar. En este caso, es nuestra responsabilidad llamar a $ apply () manualmente, lo que desencadena un ciclo de $ digest. De manera similar, si tiene una directiva que configura un detector de eventos DOM y cambia algunos modelos dentro de la función del controlador, debe llamar a $ apply () para asegurarse de que los cambios surtan efecto. La gran idea de $ apply es que podemos ejecutar un código que no conoce Angular, ese código aún puede cambiar cosas en el alcance. Si envolvemos ese código en $ apply, se encargará de llamar a $ digest (). Implementación aproximada de $ apply ().

Scope.prototype.$apply = function(expr) {
       try {
         return this.$eval(expr); //Evaluating code in the context of Scope
       } finally {
         this.$digest();
       }
};

Respondido el 06 de enero de 17 a las 08:01

AngularJS maneja el mecanismo de enlace de datos con la ayuda de tres funciones poderosas: $ reloj (),$ digest ()y $ aplicar (). La mayoría de las veces, AngularJS llamará a $ scope. $ Watch () y $ scope. $ Digest (), pero en algunos casos es posible que deba llamar a estas funciones manualmente para actualizar con nuevos valores.

$ reloj () :-

Esta función se usa para observar cambios en una variable en $ scope. Acepta tres parámetros: expresión, oyente y objeto de igualdad, donde el oyente y el objeto de igualdad son parámetros opcionales.

$ digest () -

Esta función itera a través de todos los relojes en el objeto $ scope y sus objetos secundarios $ scope
(si tiene alguno). Cuando $ digest () itera sobre los relojes, comprueba si el valor de la expresión ha cambiado. Si el valor ha cambiado, AngularJS llama al oyente con un valor nuevo y un valor antiguo. La función $ digest () se llama siempre que AngularJS cree que es necesaria. Por ejemplo, después de hacer clic en un botón o después de una llamada AJAX. Es posible que tenga algunos casos en los que AngularJS no llame a la función $ digest () por usted. En ese caso, debe llamarlo usted mismo.

$ aplicar () -

Angular actualiza automáticamente solo aquellos cambios de modelo que están dentro del contexto de AngularJS. Cuando cambia en cualquier modelo fuera del contexto Angular (como eventos DOM del navegador, setTimeout, XHR o bibliotecas de terceros), debe informar a Angular de los cambios llamando a $ apply () manualmente. Cuando la llamada a la función $ apply () finaliza, AngularJS llama a $ digest () internamente, por lo que se actualizan todos los enlaces de datos.

respondido 06 nov., 17:12

Sucedió que necesitaba vincular un modelo de datos de una persona con un formulario, lo que hice fue un mapeo directo de los datos con el formulario.

Por ejemplo, si el modelo tuviera algo como:

$scope.model.people.name

La entrada de control del formulario:

<input type="text" name="namePeople" model="model.people.name">

De esa manera, si modifica el valor del controlador de objetos, este se reflejará automáticamente en la vista.

Un ejemplo en el que pasé que el modelo se actualiza a partir de los datos del servidor es cuando solicita un código postal y un código postal basado en cargas escritas en una lista de colonias y ciudades asociadas con esa vista y, de forma predeterminada, establece el primer valor con el usuario. Y esto funciono muy bien, lo que pasa es que angularJS A veces se tarda unos segundos en actualizar el modelo, para ello puedes poner una ruleta mientras visualizas los datos.

Respondido el 06 de enero de 17 a las 08:01

Leí esta respuesta 5 veces y todavía no entiendo lo que significa aquí. - esbedulina

  1. El enlace de datos unidireccional es un enfoque en el que se toma un valor del modelo de datos y se inserta en un elemento HTML. No hay forma de actualizar el modelo desde la vista. Se utiliza en sistemas de plantillas clásicos. Estos sistemas unen datos en una sola dirección.

  2. El enlace de datos en las aplicaciones angulares es la sincronización automática de datos entre el modelo y los componentes de la vista.

El enlace de datos le permite tratar el modelo como la única fuente de verdad en su aplicación. La vista es una proyección del modelo en todo momento. Si se cambia el modelo, la vista refleja el cambio y viceversa.

Respondido el 17 de junio de 17 a las 20:06

Aquí hay un ejemplo de enlace de datos con AngularJS, usando un campo de entrada. Te lo explicare mas tarde

Código HTML

<div ng-app="myApp" ng-controller="myCtrl" class="formInput">
     <input type="text" ng-model="watchInput" Placeholder="type something"/>
     <p>{{watchInput}}</p> 
</div>

Código AngularJS

myApp = angular.module ("myApp", []);
myApp.controller("myCtrl", ["$scope", function($scope){
  //Your Controller code goes here
}]);

Como puede ver en el ejemplo anterior, AngularJS usos ng-model para escuchar y observar lo que sucede en los elementos HTML, especialmente en input campos. Cuando pase algo, haz algo. En nuestro caso, ng-model está vinculado a nuestra vista, usando la notación del bigote {{}}. Todo lo que se escriba dentro del campo de entrada se muestra en la pantalla al instante. Y esa es la belleza del enlace de datos, usando AngularJS en su forma más simple.

Espero que esto ayude.

Vea un ejemplo de trabajo aquí en Codepen

Respondido 06 Abr '16, 19:04

Soporta AngularJs Enlace de datos bidireccional.
Significa que puede acceder a los datos Ver -> Controlador & Controlador -> Ver

Por ej.

1)

// If $scope have some value in Controller. 
$scope.name = "Peter";

// HTML
<div> {{ name }} </div>

O / P

Peter

Puede vincular datos en ng-model Como:-
2)

<input ng-model="name" />

<div> {{ name }} </div>

Aquí, en el ejemplo anterior, cualquier entrada que dé el usuario, será visible en <div> etiqueta.

Si desea vincular la entrada de html al controlador: -
3)

<form name="myForm" ng-submit="registration()">
   <label> Name </lbel>
   <input ng-model="name" />
</form>

Aquí si quieres usar input name en el controlador entonces,

$scope.name = {};

$scope.registration = function() {
   console.log("You will get the name here ", $scope.name);
};

ng-model une nuestra vista y la traduce en expresión {{ }}.
ng-model son los datos que se muestran al usuario en la vista y con los que el usuario interactúa.
Por lo que es fácil vincular datos en AngularJs.

Respondido el 13 de Septiembre de 16 a las 08:09

Angular.js crea un observador para cada modelo que creamos a la vista. Siempre que se cambia un modelo, se agrega una clase "ng-dirty" al modelo, por lo que el observador observará todos los modelos que tienen la clase "ng-dirty" y actualizará sus valores en el controlador y viceversa.

Respondido 31 Oct 16, 00:10

el enlace de datos:

¿Qué es la vinculación de datos?

Siempre que el usuario cambia los datos en la vista, ocurre una actualización de ese cambio en el modelo de alcance y viceversa.

¿Como es posible?

Respuesta corta : Con la ayuda del ciclo de digestión.

Descripción: Angular js establece al observador en el modelo de alcance, que activa la función de escucha si hay un cambio en el modelo.

$scope.$watch('modelVar' , function(newValue,oldValue){

// Código de actualización de Dom con un nuevo valor

});

Entonces, ¿cuándo y cómo se llama a la función de observador?

La función de observador se llama como parte del ciclo de resumen.

El ciclo de resumen se activa automáticamente como parte de las directivas / servicios integrados de js angulares como ng-model, ng-bind, $ timeout, ng-click y otros ... que le permiten activar el ciclo de resumen.

Función de ciclo de digestión:

$scope.$digest() -> digest cycle against the current scope.
$scope.$apply() -> digest cycle against the parent scope 

es decir,$rootScope.$apply()

Nota: $ apply () es igual a $ rootScope. $ Digest () esto significa que la verificación sucia comienza desde la raíz o la parte superior o desde el alcance principal hasta todos los $ scopes secundarios en la aplicación angular js.

Las características anteriores funcionan en los navegadores IE para las versiones mencionadas también simplemente asegurándose de que su aplicación sea una aplicación angular js, lo que significa que está utilizando el archivo de script del marco angularjs al que se hace referencia en la etiqueta del script.

Gracias por su atención.

Respondido 05 Jul 18, 12:07

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.