$ observe () est une méthode sur l'objet Attributs , et en tant que telle, elle ne peut être utilisée que pour observer / surveiller le changement de valeur d'un attribut DOM. Il est uniquement utilisé / appelé directives internes. Utilisez $ observe lorsque vous devez observer / surveiller un attribut DOM qui contient une interpolation (c'est-à-dire {{}}).
Par exemple,attr1="Name: {{name}}"
puis dans une directive:attrs.$observe('attr1', ...)
.
(Si vous essayez,scope.$watch(attrs.attr1, ...)
cela ne fonctionnera pas à cause des {{}} - vous obtiendrezundefined
.) Utilisez $ watch pour tout le reste.
$ watch () est plus compliqué. Il peut observer / regarder une "expression", où l'expression peut être soit une fonction, soit une chaîne. Si l'expression est une chaîne, elle est $ parse 'd (c'est-à-dire évaluée comme une expression angulaire ) dans une fonction. (C'est cette fonction qui est appelée à chaque cycle de résumé.) L'expression de chaîne ne peut pas contenir de {{}}. $ watch est une méthode sur l'objet Scope , elle peut donc être utilisée / appelée partout où vous avez accès à un objet Scope , donc dans
- un contrôleur - n'importe quel contrôleur - créé via ng-view, ng-controller ou un contrôleur directif
- une fonction de liaison dans une directive, car elle a également accès à un champ d'application
Étant donné que les chaînes sont évaluées en tant qu'expressions angulaires, $ watch est souvent utilisé lorsque vous souhaitez observer / surveiller une propriété de modèle / portée. Par exemple,, attr1="myModel.some_prop"
puis dans une fonction de contrôleur ou de liaison: scope.$watch('myModel.some_prop', ...)
ou scope.$watch(attrs.attr1, ...)
(ou scope.$watch(attrs['attr1'], ...)
).
(Si vous essayez, attrs.$observe('attr1')
vous obtiendrez la chaîne myModel.some_prop
, ce qui n'est probablement pas ce que vous voulez.)
Comme discuté dans les commentaires sur la réponse de @ PrimosK, tous les $ observes et $ watch sont vérifiés à chaque cycle de résumé .
Les directives avec des étendues isolées sont plus compliquées. Si la syntaxe '@' est utilisée, vous pouvez $ observer ou $ regarder un attribut DOM qui contient une interpolation (c'est-à-dire {{}}). (La raison pour laquelle il fonctionne avec $ watch est parce que la syntaxe '@' fait l' interpolation pour nous, donc $ watch voit une chaîne sans {{}}.) Pour qu'il soit plus facile de se rappeler laquelle utiliser quand, je suggère d'utiliser Observer également pour ce cas.
Pour aider à tester tout cela, j'ai écrit un Plunker qui définit deux directives. Un ( d1
) ne crée pas de nouvelle étendue, l'autre ( d2
) crée une étendue isolée. Chaque directive a les six mêmes attributs. Chaque attribut est à la fois $ observé et $ surveillé.
<div d1 attr1="{{prop1}}-test" attr2="prop2" attr3="33" attr4="'a_string'"
attr5="a_string" attr6="{{1+aNumber}}"></div>
Regardez le journal de la console pour voir les différences entre $ observ et $ watch dans la fonction de liaison. Cliquez ensuite sur le lien et voyez quels $ observes et $ watch sont déclenchés par les changements de propriétés effectués par le gestionnaire de clic.
Notez que lorsque la fonction de lien s'exécute, tous les attributs qui contiennent des {{}} ne sont pas encore évalués (donc si vous essayez d'examiner les attributs, vous obtiendrez undefined
). La seule façon de voir les valeurs interpolées est d'utiliser $ observ (ou $ watch si vous utilisez une portée isolée avec '@'). Par conséquent, l'obtention des valeurs de ces attributs est une opération asynchrone . (Et c'est pourquoi nous avons besoin des fonctions $ observe et $ montre.)
Parfois, vous n'avez pas besoin de $ observe ou $ watch. Par exemple, si votre attribut contient un numéro ou un booléen (pas une chaîne), juste une fois évaluer: attr1="22"
, puis, disons, votre fonction de liaison: var count = scope.$eval(attrs.attr1)
. Si c'est juste une chaîne constante - attr1="my string"
- alors utilisez simplement attrs.attr1
dans votre directive (pas besoin de $ eval ()).
Voir aussi le message du groupe Google de Vojta sur les expressions $ watch.