Ich weiß, dass beide Watchers
und Observers
berechnet werden, sobald sich etwas $scope
in AngularJS ändert. Aber ich konnte nicht verstehen, was genau der Unterschied zwischen den beiden ist.
Mein anfängliches Verständnis ist, dass Observers
für Winkelausdrücke berechnet werden, die Bedingungen auf der HTML-Seite sind, die Watchers
ausgeführt werden, wenn die $scope.$watch()
Funktion ausgeführt wird. Denke ich richtig
javascript
angularjs
Abilash
quelle
quelle
Antworten:
$ 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 {{}}).
ZB
attr1="Name: {{name}}"
dann in einer Richtlinie :attrs.$observe('attr1', ...)
.(Wenn Sie es versuchen
scope.$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
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', ...)
oderscope.$watch(attrs.attr1, ...)
(oderscope.$watch(attrs['attr1'], ...)
).(Wenn Sie es versuchen, erhalten
attrs.$observe('attr1')
Sie die ZeichenfolgemyModel.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.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 einfachattrs.attr1
in Ihrer Direktive ($ eval () ist nicht erforderlich).Siehe auch Vojtas Google-Gruppenbeitrag über $ watch-Ausdrücke.
quelle
ng-src/ng-href
Gebrauchattr.$observe
stattscope.$watch
dann?@
Syntax austauschbar . Ich glaube, es gibt keinen Leistungsunterschied (aber ich habe mir den tatsächlichen Quellcode nicht angesehen).Wenn ich Ihre Frage richtig verstehe, fragen Sie, was der Unterschied ist, wenn Sie einen Listener-Rückruf bei registrieren
$watch
oder wenn Sie dies tun$observe
.Callback registerd with
$watch
wird ausgelöst, wenn$digest
es ausgeführt wird.Rückruf registriert mit
$observe
wird aufgerufen, wenn sich der Wert von Attributen ändert, die Interpolation enthalten (zattr="{{notJetInterpolated}}"
. B. ).Innerhalb der Direktive können Sie beide auf sehr ähnliche Weise verwenden:
oder
quelle
$digest
Phase widerspiegelt , kann davon ausgegangen werden, dass der$observe
Rückruf aufgerufen wird$digest
. Ein$watch
Rückruf wird ebenfalls aufgerufen,$digest
jedoch immer dann, wenn der Wert geändert wird. Ich denke, sie machen genau den gleichen Job: "Beobachten Sie den Ausdruck, rufen Sie die Wertänderungen zurück". Der Schlüsselwortunterschied ist möglicherweise nur syntaktischer Zucker, um den Entwickler nicht zu verwirren.Ich denke das ist ziemlich offensichtlich:
Denken Sie daran : Beide Funktionen haben zwei Argumente:
function (oldValue, newValue)
Ich habe eine gemacht plunker, damit Sie tatsächlich einen Überblick über ihre Verwendung bekommen können. Ich habe die Chamäleon-Analogie verwendet, um das Bild einfacher zu machen.
quelle
Warum unterscheidet sich $ beobachten von $ beobachten?
Die watchExpression wird ausgewertet und in jedem Digest () -Zyklus mit dem vorherigen Wert verglichen. Wenn sich der watchExpression-Wert ändert, wird die watch-Funktion aufgerufen.
$ watch ist spezifisch für das Suchen nach interpolierten Werten. Wenn der Attributwert einer Direktive interpoliert wird, z. B.
dir-attr="{{ scopeVar }}"
wird die Beobachtungsfunktion nur aufgerufen, wenn der interpolierte Wert festgelegt ist (und daher $ Digest bereits festgelegt hat, dass Aktualisierungen erforderlich sind). Grundsätzlich gibt es bereits einen Beobachter für die Interpolation, und die $ watch-Funktion huckepack davon.Siehe $ watch & $ set in compile.js
quelle