javascript - ejemplos - angularjs tutorial
AngularJS: diferencia entre los métodos $ observar y $ mirar (4)
¿Por qué $ observar es diferente a $ ver?
La watchExpression se evalúa y compara con el valor anterior de cada ciclo de digestión (), si hay un cambio en el valor de watchExpression, se llama a la función watch.
$ observar es específico para observar valores interpolados. Si se interpola el valor de atributo de una directiva, por ejemplo, dir-attr="{{ scopeVar }}"
, la función de observación solo se llamará cuando se establezca el valor interpolado (y, por lo tanto, cuando $ digest ya haya determinado las actualizaciones deben realizarse). Básicamente, ya hay un observador para la interpolación, y la función $ observe se complementa con eso.
Ver $ observar y $ establecer en compile.js
Sé que tanto los Watchers
como los Observers
se computan tan pronto como algo en el $scope
cambia en AngularJS. Pero no podía entender cuál es exactamente la diferencia entre los dos.
Mi entendimiento inicial es que los Observers
se computan para expresiones angulares que son condiciones en el lado HTML donde los Watchers
ejecutan cuando se ejecuta la función $scope.$watch()
. ¿Estoy pensando correctamente?
Creo que esto es bastante obvio:
- $ observar se utiliza en la función de enlace de las directivas.
- $ watch se usa en el alcance para observar cualquier cambio en sus valores.
Tenga en cuenta : tanto la función tiene dos argumentos,
$observe/$watch(value : string, callback : function);
- valor : es siempre una referencia de cadena al elemento observado (el nombre de la variable de un ámbito o el nombre del atributo de la directiva que se va a ver)
- devolución de llamada : la función que se ejecutará de la
function (oldValue, newValue)
formulariofunction (oldValue, newValue)
He hecho un plunker , por lo que realmente puede obtener una comprensión tanto de su utilización. He utilizado la analogía de Chameleon para facilitar la imagen.
Si entiendo bien su pregunta, está preguntando cuál es la diferencia si registra la devolución de llamada del oyente con $watch
o si lo hace con $observe
.
La devolución de llamada registrada con $watch
se activa cuando se ejecuta $digest
.
La devolución de llamada registrada con $observe
se llama cuando el valor cambia de atributos que contienen interpolación (por ejemplo, attr="{{notJetInterpolated}}"
).
Dentro de la directiva puedes usar ambos de manera muy similar:
attrs.$observe(''attrYouWatch'', function() {
// body
});
o
scope.$watch(attrs[''attrYouWatch''], function() {
// body
});
$observe() es un método en el objeto Attributes , y como tal, solo se puede usar para observar / observar el cambio de valor de un atributo DOM. Sólo se utiliza / llama dentro de las directivas. Use $ observe cuando necesite observar / observar un atributo DOM que contenga interpolación (es decir, {{}} ''s).
Por ejemplo, attr1="Name: {{name}}"
, luego en una directiva: attrs.$observe(''attr1'', ...)
.
(Si prueba el scope.$watch(attrs.attr1, ...)
no funcionará debido a las {{}} s - obtendrá undefined
.) Use $ watch para todo lo demás.
$watch() es más complicado. Puede observar / observar una "expresión", donde la expresión puede ser una función o una cadena. Si la expresión es una cadena, es $parse ''d (es decir, se evalúa como una expresión angular ) en una función. (Es esta función la que se llama en cada ciclo de resumen). La expresión de cadena no puede contener {{}}. $ watch es un método en el objeto de Scope , por lo que puede ser usado / llamado donde sea que tenga acceso a un objeto de alcance, por lo tanto, en
- un controlador - cualquier controlador - uno creado mediante ng-view, ng-controller, o un controlador directivo
- una función de enlace en una directiva, ya que tiene acceso a un ámbito de aplicación
Debido a que las cadenas se evalúan como expresiones angulares, $ watch se usa a menudo cuando se desea observar / ver una propiedad de modelo / ámbito. Por ejemplo, attr1="myModel.some_prop"
, luego en una función de controlador o enlace: scope.$watch(''myModel.some_prop'', ...)
o scope.$watch(attrs.attr1, ...)
(o scope.$watch(attrs[''attr1''], ...)
).
(Si prueba attrs.$observe(''attr1'')
obtendrá la cadena myModel.some_prop
, que probablemente no sea lo que desea).
Como se comentó en los comentarios sobre la respuesta de @ PrimosK, todos los $ observos y $ relojes se verifican en cada ciclo de resumen .
Las directivas con ámbitos aislados son más complicadas. Si se usa la sintaxis ''@'', puede $ observar o $ ver un atributo DOM que contiene interpolación (es decir, {{}} ''s). (La razón por la que funciona con $ watch es porque la sintaxis ''@'' hace la interpolation para nosotros, por lo tanto, $ watch ve una cadena sin {{}} ''s). Para que sea más fácil recordar cuál usar cuándo, sugiero usar $ Observar para este caso también.
Para ayudar a probar todo esto, escribí un Plunker que define dos directivas. Uno ( d1
) no crea un nuevo alcance, el otro ( d2
) crea un alcance aislado. Cada directiva tiene los mismos seis atributos. Cada atributo es $ observado y $ vigilado.
<div d1 attr1="{{prop1}}-test" attr2="prop2" attr3="33" attr4="''a_string''"
attr5="a_string" attr6="{{1+aNumber}}"></div>
Mire el registro de la consola para ver las diferencias entre $ observe y $ watch en la función de enlace. Luego haga clic en el enlace y vea qué $ observos y $ relojes se activan por los cambios de propiedad realizados por el controlador de clic.
Tenga en cuenta que cuando se ejecuta la función de enlace, los atributos que contienen {{}} no se evalúan todavía (por lo tanto, si intenta examinar los atributos, quedará undefined
). La única forma de ver los valores interpolados es usar $ observe (o $ watch si se usa un alcance aislado con ''@''). Por lo tanto, obtener los valores de estos atributos es una operación asíncrona . (Y es por eso que necesitamos las funciones $ observar y $ ver).
A veces no necesitas $ observar o $ ver. Por ejemplo, si su atributo contiene un número o un valor booleano (no una cadena), simplemente attr1="22"
una vez: attr1="22"
, luego en, digamos, su función de enlace: var count = scope.$eval(attrs.attr1)
. Si es solo una cadena constante - attr1="my string"
- entonces use attrs.attr1
en su directiva (no necesita $ eval ()).
Ver también la publicación de grupo de google de Vojta sobre expresiones de $ watch.