Wie funktioniert das Binden und Verdauen in AngularJS?


76

Eine Sache, die AngularJS von anderen JavaScript-MVC-Frameworks unterscheidet, ist die Fähigkeit, gebundene Werte aus JavaScript mithilfe von Bindungen in HTML wiederzugeben. Angular tut dies "automatisch", wenn Sie der Variablen $ scope einen beliebigen Wert zuweisen.

Aber wie automatisch ist das? Manchmal nimmt Angular die Änderung nicht auf, daher muss ich $ scope. $ Apply () oder $ scope. $ Digest () aufrufen, um Angular zu informieren, dass die Änderung übernommen werden soll. Wenn ich eine dieser Methoden ausführe, wird manchmal ein Fehler ausgegeben und es wird angezeigt, dass bereits ein Digest ausgeführt wird.

Da die Bindungen (alles in {{}} geschweiften Klammern oder ng-Attributen) mit eval wiedergegeben werden, bedeutet dies, dass Angular das $ scope-Objekt ständig abfragt, um nach Änderungen zu suchen, und dann eine Auswertung durchführt, um diese Änderungen in das DOM / zu übertragen HTML? Oder hat AngularJS irgendwie herausgefunden, welche magischen Variablen verwendet werden, um Ereignisse auszulösen, die ausgelöst werden, wenn sich ein Variablenwert ändert oder zugewiesen wird? Ich habe noch nie davon gehört, dass es von allen Browsern vollständig unterstützt wird, daher bezweifle ich es.

Wie verfolgt AngularJS seine Bindungen und Bereichsvariablen?


5
Ich fand den Abschnitt in docs.angularjs.org/guide/concepts#runtime , der mit "Hier ist die Erklärung, wie das Hello World-Beispiel den Datenbindungseffekt erzielt" beginnt, hilfreich.
Mark Rajcok

3
Dieser Beitrag ist auch nützlich, wenn Sie ihn noch nicht gesehen haben: stackoverflow.com/questions/9682092/databinding-in-angularjs/…
Gloopy

Kommentar zu Ihrem ersten deklarativen Absatz: Angulars "Fähigkeit, gebundene Werte aus JavaScript mithilfe von Bindungen in HTML wiederzugeben" klingt nach einer verwirrenden Art, "Datenbindung" zu sagen. Und zu diesem Zeitpunkt unterscheidet es Angular nicht wirklich von anderen Frameworks wie Ember oder React. Die Frage ist nützlich, versteh mich nicht falsch. Aber dieser erste Absatz ist nur eine Meinung, mit der ich nicht einverstanden bin - ich würde die Frage bearbeiten, aber ich fühle mich nicht maßgebend genug.
Jorge Orpinel

Antworten:


64

Zusätzlich zu dem von Mark gefundenen Dokumentationsabschnitt können wir meiner Meinung nach versuchen, alle möglichen Änderungsquellen aufzuzählen.

  1. Benutzerinteraktion mit HTML-Eingaben ( 'Text' , 'Nummer' , 'URL' , 'E-Mail' , 'Radio' , 'Kontrollkästchen' ). AngularJS hat inputDirective . Die Eingaben "Text", "Nummer", "URL" und "E-Mail" binden den Listener-Handler für "Eingabe" - oder "Keydown" -Ereignisse. Der Listener-Handler ruft den Bereich auf. $ Apply . 'radio' und 'checkbox' binden einen ähnlichen Handler für das Klickereignis.
  2. Benutzerinteraktion mit ausgewähltem Element. AngularJS hat selectDirective mit ähnlichem Verhalten beim ' change' -Ereignis.
  3. Periodische Änderungen mit dem $ timeout-Dienst , der auch $ rootScope ausführt. $ Apply () .
  4. eventDirectives (ngClick usw.) verwenden ebenfalls scope. $ apply .
  5. $ http verwendet auch $ rootScope. $ apply () .
  6. Änderungen außerhalb der AngularJS-Welt sollten den Gültigkeitsbereich verwenden. $ Wie Sie wissen, gelten.

2
+1 für Punkt "5. $ http verwendet auch $ rootScope. $ Apply ()." Argh. Weiß jemand, warum sie das tun? Das ist sehr ärgerlich ...
Gecco

5

Wie Sie herausgefunden haben, handelt es sich nicht um eine Abfrage, sondern um die Verwendung der internen Ausführungsschleife. Deshalb müssen Sie $ apply () oder $ Digest () verwenden, um Dinge in Bewegung zu setzen.

Miškos Erklärung ist ziemlich gründlich, aber das Fehlende ist, dass Angular nur versucht, $ scope wieder in einen klaren internen Zustand zu bringen, wenn etwas in seinem eigenen Kontext passiert. Dies kann einige Zeit in Anspruch nehmen, um zwischen den Modellzuständen hin und her zu springen. Deshalb können Sie sich auch nicht darauf verlassen, dass $ watch () nur einmal ausgelöst wird, und Sie sollten auch vorsichtig sein, wenn Sie Beziehungen zwischen Modellen manuell einrichten, da Sie sonst endlos werden Rundschreiben aktualisiert.


Wie funktioniert das $ apply (someFn)? Wird der Inhalt von someFn ausgeführt, wenn die Anwendungsiteration ausgeführt wird?
Matsko

Mit $ apply wird der Code im Angular-Bereich ausgeführt, um nur zu benachrichtigen, dass die Änderungen verarbeitet werden sollen. Siehe: docs.angularjs.org/api/ng.$rootScope.Scope#$apply
dain

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.