$ observe () é um método noobjeto Atributos e, como tal, só pode ser usado para observar / observar a alteração de valor de um atributo DOM. Só é usado / chamado dentro de diretivas. Use $ observe quando precisar observar / observar um atributo DOM que contenha interpolação (ou seja, {{}} ').
Por exemplo,attr1="Name: {{name}}"
e depois numa directiva:attrs.$observe('attr1', ...)
.
(Se você tentarscope.$watch(attrs.attr1, ...)
, não funcionará por causa dos {{}} s - você receberáundefined
.) Use $ watch para todo o resto.
$ watch () é mais complicado. Ele pode observar / observar uma "expressão", onde a expressão pode ser uma função ou uma string. Se a expressão for uma string, é $ parse 'd (isto é, avaliado como uma expressão Angular ) em uma função. (É essa função que é chamada todo ciclo de digestão.) A expressão da string não pode conter {{}} 's. $ watch é um método noobjeto Scope , portanto, pode ser usado / chamado sempre que você tiver acesso a um objeto de escopo, portanto, em
- um controlador - qualquer controlador - um criado via ng-view, ng-controller ou um controlador de diretiva
- uma função de vinculação em uma diretiva, pois ela também tem acesso a um escopo
Como as seqüências de caracteres são avaliadas como expressões angulares, $ watch geralmente é usado quando você deseja observar / observar uma propriedade de modelo / escopo. Por exemplo, attr1="myModel.some_prop"
em uma função de controlador ou link: scope.$watch('myModel.some_prop', ...)
ou scope.$watch(attrs.attr1, ...)
(ou scope.$watch(attrs['attr1'], ...)
).
(Se você tentar, attrs.$observe('attr1')
obterá a string myModel.some_prop
, o que provavelmente não é o que você deseja.)
Conforme discutido nos comentários da resposta do @ PrimosK, todos os $ observes e $ watches são verificados a cada ciclo de digestão .
Diretivas com escopos isolados são mais complicadas. Se a sintaxe '@' for usada, você pode $ observar ou $ assistir um atributo DOM que contenha interpolação (ou seja, {{}} '). (O motivo pelo qual ele trabalha com $ watch é porque a sintaxe '@' faz a interpolação para nós, portanto, $ watch vê uma string sem {{}} '.) Para facilitar a lembrança de qual usar, sugiro usar $ observe também para este caso.
Para ajudar a testar tudo isso, escrevi um Plunker que define duas diretivas. Um ( d1
) não cria um novo escopo, o outro ( d2
) cria um escopo isolado. Cada diretiva tem os mesmos seis atributos. Cada atributo é $ observe'd e $ watch'ed.
<div d1 attr1="{{prop1}}-test" attr2="prop2" attr3="33" attr4="'a_string'"
attr5="a_string" attr6="{{1+aNumber}}"></div>
Veja o log do console para ver as diferenças entre $ observe e $ watch na função de vinculação. Em seguida, clique no link e veja quais $ observa e $ relógios são acionados pelas alterações de propriedade feitas pelo manipulador de cliques.
Observe que quando a função de link é executada, quaisquer atributos que contenham {{}} ainda não são avaliados (portanto, se você tentar examinar os atributos, obterá undefined
). A única maneira de ver os valores interpolados é usar $ observe (ou $ watch se estiver usando um escopo isolado com '@'). Portanto, obter os valores desses atributos é uma operação assíncrona . (E é por isso que precisamos das funções $ observe e $ watch.)
Às vezes você não precisa de $ observe ou $ watch. Por exemplo, se o seu atributo contém um número ou um booleano (não uma string), apenas avaliá-lo uma vez: attr1="22"
e, em seguida, digamos, a sua função que relaciona: var count = scope.$eval(attrs.attr1)
. Se for apenas uma string constante - attr1="my string"
- apenas use attrs.attr1
na sua diretiva (não é necessário $ eval ()).
Veja também o post do grupo do Google sobre Vojta sobre expressões $ watch.