Buscar..


Sintaxis

  • $ scope. $ watch (watchExpression, callback, [deep compare])
  • $ scope. $ digest ()
  • $ scope. $ apply ([exp])

enlace de datos de dos vías

Angular tiene algo de magia bajo su capucha. permite vincular DOM a variables js reales.

Angular utiliza un bucle, denominado " bucle de resumen ", que se llama después de cualquier cambio de una variable: llamadas devoluciones de llamada que actualizan el DOM.

Por ejemplo, la directiva ng-model adjunta un keyup eventListener a esta entrada:

<input ng-model="variable" />

Cada vez que se dispara el evento keyup , se inicia el bucle de digestión .

En algún momento, el bucle de resumen itera sobre una devolución de llamada que actualiza el contenido de este intervalo:

<span>{{variable}}</span>

El ciclo de vida básico de este ejemplo, resume (muy esquemáticamente) cómo funciona el ángulo:

  1. Escaneo angular html
    • ng-model directiva ng-model crea una escucha keyup en la entrada
    • expression dentro de span agrega una devolución de llamada al ciclo de digestión
  2. El usuario interactúa con la entrada
    • keyup oyente keyup comienza el ciclo de digerir
    • ciclo de digestión de las calles la devolución de llamada
    • La devolución de llamada actualiza los contenidos de span.

$ digerir y $ ver

La implementación del enlace de datos de dos vías, para lograr el resultado del ejemplo anterior, se podría realizar con dos funciones principales:

  • $ digest se llama después de una interacción del usuario (vinculación DOM => variable)
  • $ watch establece una devolución de llamada para que se llame después de los cambios de la variable (variable de enlace => DOM)

nota: este es un ejemplo es una demostración, no el código angular real


<input id="input"/>
<span id="span"></span>

Las dos funciones que necesitamos:

var $watches = [];
function $digest(){
    $watches.forEach(function($w){
        var val = $w.val();
        if($w.prevVal !== val){
            $w.callback(val, $w.prevVal);
            $w.prevVal = val;
        }
    })
}
function $watch(val, callback){
    $watches.push({val:val, callback:callback, prevVal: val() })
}

Ahora podríamos usar estas funciones para conectar una variable al DOM (angular viene con directivas integradas que lo harán por usted):

var realVar;    
//this is usually done by ng-model directive
input1.addEventListener('keyup',function(e){
    realVar=e.target.value; 
    $digest()
}, true);

//this is usually done with {{expressions}} or ng-bind directive
$watch(function(){return realVar},function(val){
    span1.innerHTML = val;
});

Por supuesto, las implementaciones reales son más complejas y admiten parámetros como el elemento a enlazar y la variable a usar.

Un ejemplo de ejecución se puede encontrar aquí: https://jsfiddle.net/azofxd4j/

el arbol $ scope

El ejemplo anterior es lo suficientemente bueno cuando necesitamos vincular un solo elemento html a una sola variable.

En realidad, necesitamos unir muchos elementos a muchas variables:

<span ng-repeat="number in [1,2,3,4,5]">{{number}}</span>

Esta ng-repeat une 5 elementos a 5 variables llamadas number , ¡con un valor diferente para cada una de ellas!


La forma en que angular logra este comportamiento es mediante el uso de un contexto separado para cada elemento que necesita variables separadas. Este contexto se llama un alcance.

Cada ámbito contiene propiedades, que son las variables vinculadas al DOM, y las funciones $digest y $watch se implementan como métodos del alcance.

El DOM es un árbol, y las variables deben usarse en diferentes niveles del árbol:

<div>
    <input ng-model="person.name" />
    <span ng-repeat="number in [1,2,3,4,5]">{{number}} {{person.name}}</span>
</div>

Pero como vimos, el contexto (o alcance) de las variables dentro de ng-repeat es diferente al contexto que se encuentra arriba. Para resolver esto - angular implementa ámbitos como un árbol.

Cada alcance tiene una variedad de hijos, y llamar a su método $digest ejecutará todo su método $digest niños.

De esta manera, después de cambiar la entrada, se llama $digest para el alcance del div, que luego ejecuta $digest para sus 5 hijos, que actualizará su contenido.


Una implementación simple para un alcance, podría verse así:

function $scope(){
    this.$children = [];
    this.$watches = [];
}

$scope.prototype.$digest = function(){
    this.$watches.forEach(function($w){
        var val = $w.val();
        if($w.prevVal !== val){
            $w.callback(val, $w.prevVal);
          $w.prevVal = val;
        }
    });
    this.$children.forEach(function(c){
        c.$digest();
    });
}

$scope.prototype.$watch = function(val, callback){
    this.$watches.push({val:val, callback:callback, prevVal: val() })
}

nota: este es un ejemplo es una demostración, no el código angular real



Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow