$ observe () es un método en elobjeto Atributos y, como tal, solo se puede usar para observar / observar el cambio de valor de un atributo DOM. Solo se usa / llama dentro de las directivas. Use $ observe cuando necesite observar / mirar un atributo DOM que contiene interpolación (es decir, {{}} 's).
Por ejemplo,attr1="Name: {{name}}"
y luego en una directiva:attrs.$observe('attr1', ...)
.
(Si lo intentasscope.$watch(attrs.attr1, ...)
no funcionará debido a los {{}} s, obtendrásundefined
). Usa $ watch para todo lo demás.
$ watch () es más complicado. Puede observar / mirar 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, evaluada como una expresión angular ) en una función. (Es esta función la que se llama cada ciclo de resumen.) La expresión de cadena no puede contener {{}}. $ watch es un método en elobjeto Scope , por lo que se puede usar / invocar donde tenga acceso a un objeto Scope , por lo tanto, en
- un controlador, cualquier controlador, uno creado a través de ng-view, ng-controller o un controlador directivo
- una función de enlace en una directiva, ya que también tiene acceso a un alcance
Debido a que las cadenas se evalúan como expresiones angulares, $ watch se usa a menudo cuando desea observar / mirar una propiedad de modelo / alcance. 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 lo intentas attrs.$observe('attr1')
, obtendrás la cadena myModel.some_prop
, que probablemente no sea lo que deseas).
Como se discutió en los comentarios sobre la respuesta de @ PrimosK, todos los $ observa y los $ 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 $ mirar 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 interpolación por 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 tanto $ obser'd como $ watch'ed.
<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é $ observa y $ relojes son activados por los cambios de propiedad realizados por el controlador de clics.
Tenga en cuenta que cuando se ejecuta la función de enlace, los atributos que contienen {{}} aún no se evalúan (por lo tanto, si intenta examinar los atributos, obtendrá undefined
). La única forma de ver los valores interpolados es usar $ observe (o $ watch si usa un alcance aislado con '@'). Por lo tanto, obtener los valores de estos atributos es una operación asincrónica . (Y es por eso que necesitamos las funciones $ observe y $ watch).
A veces no necesitas $ observar o $ mirar. Por ejemplo, si el atributo contiene un número o un valor lógico (no una cadena), justo evaluar una vez: attr1="22"
y, a continuación, digamos, en su función de vinculación: var count = scope.$eval(attrs.attr1)
. Si se trata solo de una cadena constante, attr1="my string"
simplemente utilícela attrs.attr1
en su directiva (no necesita $ eval ())
Vea también la publicación del grupo de Google de Vojta sobre las expresiones $ watch.