Sie müssen sich darüber im Klaren sein, wie AngularJS funktioniert, um es zu verstehen.
Digest-Zyklus und $scope
Zunächst definiert AngularJS ein Konzept eines sogenannten Digest-Zyklus. Dieser Zyklus kann als eine Art Schleife betrachtet werden, während der AngularJS überprüft, ob es Änderungen an allen Variablen gibt, die von allen $scope
s überwacht werden. Wenn also $scope.myVar
in Ihrem Controller definiert ist und diese Variable als überwacht markiert wurde, teilen Sie AngularJS implizit mit, die Änderungen an myVar
in jeder Iteration der Schleife zu überwachen.
Eine naheliegende Frage wäre: Wird alles, was an $scope
angehängt ist, überwacht? Glücklicherweise nein. Wenn Sie nach Änderungen an jedem Objekt in Ihrem $scope
suchen würden, würde eine Digest-Schleife schnell lange dauern, um ausgewertet zu werden, und Sie würden schnell auf Leistungsprobleme stoßen. Deshalb hat uns das AngularJS-Team zwei Möglichkeiten gegeben, eine $scope
-Variable als überwacht zu deklarieren (lesen Sie unten).
$watch hilft, auf $scope-Änderungen zu hören
Es gibt zwei Möglichkeiten, eine $scope
-Variable als überwacht zu deklarieren.
- Indem Sie es in Ihrem Template über den Ausdruck
{{myVar}}
verwenden
- Indem Sie es manuell über den
$watch
-Service hinzufügen
Ad 1) Dies ist das häufigste Szenario und ich bin sicher, Sie haben es bereits gesehen, wussten aber nicht, dass dadurch im Hintergrund eine Überwachung erstellt wurde. Ja, das war der Fall! Die Verwendung von AngularJS-Direktiven (wie z.B. ng-repeat
) kann auch implizite Überwachungen erstellen.
Ad 2) So erstellen Sie Ihre eigenen Überwachungen. Der $watch
-Service hilft Ihnen dabei, Code auszuführen, wenn sich ein Wert, der an den $scope
angehängt ist, geändert hat. Es wird selten verwendet, ist aber manchmal hilfreich. Wenn Sie beispielsweise jedes Mal Code ausführen möchten, wenn sich 'myVar' ändert, könnten Sie folgendes tun:
function MyController($scope) {
$scope.myVar = 1;
$scope.$watch('myVar', function() {
alert('hey, myVar has changed!');
});
$scope.buttonClicked = function() {
$scope.myVar = 2; // Dadurch wird der Ausdruck $watch aktiviert
};
}
$apply ermöglicht die Integration von Änderungen in den Digest-Zyklus
Sie können die Funktion $apply
als Integrationsmechanismus betrachten. Jedes Mal, wenn Sie eine überwachte Variable, die an das $scope
-Objekt angehängt ist, direkt ändern, wird AngularJS wissen, dass die Änderung stattgefunden hat. Dies liegt daran, dass AngularJS bereits wusste, diese Änderungen zu überwachen. Wenn dies im vom Framework verwalteten Code passiert, wird der Digest-Zyklus fortgesetzt.
Manchmal möchten Sie jedoch einen Wert außerhalb der AngularJS-Welt ändern und die Änderungen normal propagieren sehen. Angenommen, Sie haben einen Wert $scope.myVar
, der innerhalb eines jQuery-$.ajax()
-Handlers geändert wird. Dies wird irgendwann in der Zukunft passieren. AngularJS kann nicht auf das Warten, da es nicht angewiesen wurde, auf jQuery zu warten.
Dafür wurde $apply
eingeführt. Es ermöglicht Ihnen, den Digestionszyklus explizit zu starten. Sie sollten dies jedoch nur verwenden, um Daten zu AngularJS zu migrieren (Integration mit anderen Frameworks), aber niemals diese Methode mit normalem AngularJS-Code kombinieren, da AngularJS sonst einen Fehler ausgibt.
Wie hängt das alles mit dem DOM zusammen?
Nun sollten Sie das Tutorial noch einmal durchgehen, jetzt, da Sie all dies wissen. Der Digest-Zyklus stellt sicher, dass die Benutzeroberfläche und der JavaScript-Code synchron bleiben, indem er in jeder Iteration aller an alle $scope
s angehängten Beobachter auswertet, solange nichts passiert. Wenn keine weiteren Änderungen im Digest-Zyklus auftreten, gilt dieser als beendet.
Sie können Objekte entweder explizit im Controller an das $scope
-Objekt anhängen oder sie direkt im View-Template in {{expression}}
-Form deklarieren.
Weitere Informationen: