$ observ () è un metodosull'oggetto Attributes e, come tale, può essere utilizzato solo per osservare / osservare la modifica del valore di un attributo DOM. Viene utilizzato / chiamato solo all'interno delle direttive. Utilizzare $ observ quando è necessario osservare / guardare un attributo DOM che contiene interpolazione (ovvero {{}}).
Ad esempio,attr1="Name: {{name}}"
e poi in una direttiva:attrs.$observe('attr1', ...)
.
(Se proviscope.$watch(attrs.attr1, ...)
, non funzionerà a causa dei {{}} - otterraiundefined
.) Usa $ watch per tutto il resto.
$ watch () è più complicato. Può osservare / guardare una "espressione", in cui l'espressione può essere una funzione o una stringa. Se l'espressione è una stringa, è $ parse 'd (ovvero, valutata come espressione angolare ) in una funzione. (È questa funzione che si chiama ogni ciclo digest.) L'espressione stringa non può contenere {{}}. $ watch è un metodosull'oggetto Scope , quindi può essere usato / chiamato ovunque tu abbia accesso a un oggetto scope, quindi in
- un controller - qualsiasi controller - uno creato tramite ng-view, ng-controller o un controller direttiva
- una funzione di collegamento in una direttiva, poiché anche questa ha accesso a un ambito
Poiché le stringhe vengono valutate come espressioni angolari, $ watch viene spesso utilizzato quando si desidera osservare / guardare una proprietà modello / ambito. Ad esempio, attr1="myModel.some_prop"
quindi in un controller o in una funzione di collegamento: scope.$watch('myModel.some_prop', ...)
o scope.$watch(attrs.attr1, ...)
(o scope.$watch(attrs['attr1'], ...)
).
(Se provi attrs.$observe('attr1')
otterrai la stringa myModel.some_prop
, che probabilmente non è quello che vuoi.)
Come discusso nei commenti sulla risposta di @ PrimosK, tutti i $ osservati e $ orologi vengono controllati ad ogni ciclo digest .
Le direttive con ambiti isolati sono più complicate. Se viene utilizzata la sintassi "@", è possibile $ osservare o $ guardare un attributo DOM che contiene interpolazione (ovvero {{}}). (Il motivo per cui funziona con $ watch è perché la sintassi '@' fa l' interpolazione per noi, quindi $ watch vede una stringa senza {{}}.) Per rendere più facile ricordare quale usare quando, suggerisco di usare $ osservare anche per questo caso.
Per aiutare a testare tutto ciò, ho scritto un Plunker che definisce due direttive. Uno ( d1
) non crea un nuovo ambito, l'altro ( d2
) crea un ambito isolato. Ogni direttiva ha gli stessi sei attributi. Ogni attributo è sia $ osservato che $ osservato.
<div d1 attr1="{{prop1}}-test" attr2="prop2" attr3="33" attr4="'a_string'"
attr5="a_string" attr6="{{1+aNumber}}"></div>
Guarda il registro della console per vedere le differenze tra $ observ e $ watch nella funzione di collegamento. Quindi fare clic sul collegamento e vedere quali $ osserva e $ orologi sono attivati dalle modifiche alle proprietà apportate dal gestore dei clic.
Si noti che quando viene eseguita la funzione di collegamento, tutti gli attributi che contengono {{}} non vengono ancora valutati (quindi se si tenta di esaminare gli attributi, si ottiene undefined
). L'unico modo per visualizzare i valori interpolati è utilizzare $ observ (o $ watch se si utilizza un ambito isolato con '@'). Pertanto, ottenere i valori di questi attributi è un'operazione asincrona . (Ed è per questo che abbiamo bisogno delle funzioni $ observ e $ watch.)
A volte non hai bisogno di $ osservare o $ guardare. Ad esempio, se il vostro attributo contiene un numero o un valore booleano (non una stringa), basta valutare una volta: attr1="22"
e poi, per esempio, la funzione di collegamento: var count = scope.$eval(attrs.attr1)
. Se è solo una stringa costante - attr1="my string"
- allora usa solo attrs.attr1
nella tua direttiva (non c'è bisogno di $ eval ()).
Vedi anche il post del gruppo google di Vojta sulle espressioni $ watch.