$ watch () ist eine Methode für das Attributes- Objekt und kann daher nur zum Beobachten / Beobachten der Wertänderung eines DOM-Attributs verwendet werden. Es wird nur in Direktiven verwendet / aufgerufen. Verwenden Sie $ beobachten, wenn Sie ein DOM-Attribut beobachten / beobachten müssen, das Interpolation enthält (dh {{}}).
ZBattr1="Name: {{name}}"
dann in einer Richtlinie :attrs.$observe('attr1', ...)
.
(Wenn Sie es versuchenscope.$watch(attrs.attr1, ...)
, funktioniert es aufgrund der {{}} s nicht - Sie erhaltenundefined
.) Verwenden Sie $ watch für alles andere.
$ watch () ist komplizierter. Es kann einen "Ausdruck" beobachten / beobachten, wobei der Ausdruck entweder eine Funktion oder eine Zeichenfolge sein kann. Wenn der Ausdruck eine Zeichenfolge ist, wird $ parse 'd (dh als Winkelausdruck ausgewertet) in eine Funktion umgewandelt. (Diese Funktion wird bei jedem Digest-Zyklus aufgerufen.) Der Zeichenfolgenausdruck darf keine {{}} enthalten. $ watch ist eine Methode für das Scope- Objekt, sodass sie überall dort verwendet / aufgerufen werden kann, wo Sie Zugriff auf ein Scope-Objekt haben
- Ein Controller - ein beliebiger Controller - einer, der über ng-view, ng-controller oder einen Direktiven-Controller erstellt wurde
- eine Verknüpfungsfunktion in einer Direktive, da diese auch Zugriff auf einen Bereich hat
Da Zeichenfolgen als Winkelausdrücke ausgewertet werden, wird $ watch häufig verwendet, wenn Sie eine Modell- / Bereichseigenschaft beobachten / beobachten möchten. ZB attr1="myModel.some_prop"
dann in einer Controller- oder Link-Funktion: scope.$watch('myModel.some_prop', ...)
oder scope.$watch(attrs.attr1, ...)
(oder scope.$watch(attrs['attr1'], ...)
).
(Wenn Sie es versuchen, erhalten attrs.$observe('attr1')
Sie die Zeichenfolge myModel.some_prop
, die wahrscheinlich nicht Ihren Wünschen entspricht.)
Wie in den Kommentaren zur Antwort von @ PrimosK erläutert, werden alle $ Beobachtungen und $ Uhren in jedem Verdauungszyklus überprüft .
Richtlinien mit isolierten Bereichen sind komplizierter. Wenn die '@' - Syntax verwendet wird, können Sie ein DOM-Attribut, das Interpolation enthält (dh {{}}) , $ beobachten oder $ beobachten . (Der Grund, warum es mit $ watch funktioniert, ist, dass die '@' - Syntax die Interpolation für uns übernimmt. Daher sieht $ watch einen String ohne {{}}.) Um sich leichter zu merken, welcher wann verwendet werden soll, schlage ich vor, ihn zu verwenden $ auch für diesen Fall beachten.
Um all dies zu testen, habe ich einen Plunker geschrieben , der zwei Anweisungen definiert. One ( d1
) erstellt keinen neuen Bereich, der andere ( d2
) erstellt einen isolierten Bereich. Jede Direktive hat die gleichen sechs Attribute. Jedes Attribut wird sowohl $ beobachtet als auch $ beobachtet.
<div d1 attr1="{{prop1}}-test" attr2="prop2" attr3="33" attr4="'a_string'"
attr5="a_string" attr6="{{1+aNumber}}"></div>
Sehen Sie sich das Konsolenprotokoll an, um die Unterschiede zwischen $ watch und $ watch in der Verknüpfungsfunktion zu sehen. Klicken Sie dann auf den Link und sehen Sie, welche $ Beobachtungen und $ Uhren durch die vom Klick-Handler vorgenommenen Eigenschaftsänderungen ausgelöst werden.
Beachten Sie, dass beim Ausführen der Verknüpfungsfunktion alle Attribute, die {{}} enthalten, noch nicht ausgewertet werden (wenn Sie also versuchen, die Attribute zu untersuchen, erhalten Sie undefined
). Die einzige Möglichkeit, die interpolierten Werte anzuzeigen, ist die Verwendung von $ watch (oder $ watch, wenn ein isolierter Bereich mit '@' verwendet wird). Daher ist das Abrufen der Werte dieser Attribute eine asynchrone Operation. (Und deshalb brauchen wir die Funktionen $ watch und $ watch.)
Manchmal braucht man nicht $ beobachten oder $ beobachten. Wenn Ihr Attribut beispielsweise eine Zahl oder einen Booleschen Wert (keine Zeichenfolge) enthält, werten Sie ihn nur einmal aus: attr1="22"
Dann beispielsweise in Ihrer Verknüpfungsfunktion : var count = scope.$eval(attrs.attr1)
. Wenn es sich nur um eine konstante Zeichenfolge handelt - attr1="my string"
- verwenden Sie sie einfach attrs.attr1
in Ihrer Direktive ($ eval () ist nicht erforderlich).
Siehe auch Vojtas Google-Gruppenbeitrag über $ watch-Ausdrücke.