Frage Wie funktioniert die Bindung und Verdauung in AngularJS?


Eine Sache, die AngularJS von anderen JavaScript-MVC-Frameworks abhebt, ist die Fähigkeit, gebundene Werte von JavaScript mit Hilfe von Bindings in HTML zu spiegeln. Angular führt dies "automatisch" aus, wenn Sie der Variablen $ scope einen Wert zuweisen.

Aber wie automatisch ist das? Manchmal nimmt Angular die Änderung nicht auf, so dass ich $ scope aufrufen muss. $ Apply () oder $ scope. $ Digest (), um angular zu informieren, um die Änderung aufzunehmen. Manchmal, wenn ich eine dieser Methoden ausfühle, wird ein Fehler ausgegeben, der besagt, dass bereits ein Digest ausgeführt wird.

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

Wie verfolgt AngularJS seine Bindings und Scope-Variablen?


76
2017-09-17 16:57


Ursprung


Antworten:


In Ergänzung zu Dokumentationsabschnitt von Mark gefunden Ich denke, wir können versuchen, alle möglichen Quellen der Veränderung aufzuzählen.

  1. Benutzerinteraktion mit HTML-Eingaben ('Text', 'Nummer', "URL", 'Email', 'Radio', "Kontrollkästchen"). AngularJS hat Eingabedirektiv. Eingaben 'text', 'number', 'url' und 'email' binden Listener-Handler für "Eingabe" oder "Keydown" -Ereignisse. Listener-Handler ruft scope auf. $ apply. 'radio' und 'checkbox' binden ähnliche Handler für Klick-Events.
  2. Benutzerinteraktion mit Auswahlelement AngularJS hat selectDirective mit ähnlichem Verhalten beim Ereignis 'Ändern'.
  3. Periodische Änderungen mit $ Timeout-Dienst das auch tun $ rootScope. $ apply ().
  4. EreignisDirektiven (ngClick, etc) verwenden Sie auch Bereich. $ gelten.
  5. $ http verwendet auch $ rootScope. $ apply ().
  6. Änderungen außerhalb der AngularJS-Welt sollten den Geltungsbereich verwenden. $ Apply, wie Sie wissen.

64
2017-09-19 08:52



Wie Sie herausgefunden haben, ist es kein Polling, sondern die interne Ausführungsschleife. Deshalb müssen Sie $ apply () oder $ digest () verwenden, um Dinge in Bewegung zu versetzen.

Miškos Erklärung ist ziemlich gründlich, aber das bisschen fehlt ist, dass Angular gerade versucht, $ scope wieder in einen klaren internen Zustand zu bringen, wenn etwas in seinem eigenen Kontext passiert. Dies kann einige Zwischenstopps zwischen den Modellzuständen erfordern, weshalb Sie sich auch nicht darauf verlassen können, dass $ watch () nur einmal ausgelöst wird und warum Sie vorsichtig sein sollten, wenn Sie Beziehungen zwischen Modellen manuell einrichten oder endlos sein wollen kreisförmige Aktualisierungen


5
2017-09-19 00:23