it-swarm.com.de

Wie funktioniert die Datenbindung in AngularJS?

Wie funktioniert die Datenbindung im Rahmen von AngularJS?

Ich habe keine technischen Details zu deren Website gefunden. Es ist mehr oder weniger klar, wie es funktioniert, wenn Daten von Ansicht zu Modell übertragen werden. Aber wie verfolgt AngularJS Änderungen von Modelleigenschaften ohne Setter und Getter?

Ich habe festgestellt, dass es JavaScript-Beobachter gibt, die diese Arbeit erledigen können. Sie werden jedoch in Internet Explorer 6 und Internet Explorer 7 nicht unterstützt. Woher weiß AngularJS, dass ich zum Beispiel Folgendes geändert und diese Änderung in einer Ansicht wiedergegeben habe?

myobject.myproperty="new value";
1906
Pashec

AngularJS merkt sich den Wert und vergleicht ihn mit einem vorherigen Wert. Dies ist eine grundlegende Schmutzprüfung. Wenn sich der Wert ändert, wird das Änderungsereignis ausgelöst.

Die $apply() -Methode, die Sie beim Übergang von einer Nicht-AngularJS-Welt in eine AngularJS-Welt aufrufen, ruft $digest() auf. Ein Digest ist einfach nur altes Dirty-Checking. Es funktioniert in allen Browsern und ist absolut vorhersehbar.

Dirty-Checking (AngularJS) im Gegensatz zu Change Listener ( KnockoutJS und Backbone.js ): Während Dirty-Checking einfach und sogar ineffizient erscheint (darauf werde ich später eingehen ), es stellt sich heraus, dass es die ganze Zeit semantisch korrekt ist, während Change Listener viele seltsame Eckfälle haben und Dinge wie das Nachverfolgen von Abhängigkeiten benötigen, um es semantisch korrekter zu machen. KnockoutJS Dependency Tracking ist eine clevere Funktion für ein Problem, das AngularJS nicht hat.

Probleme mit Änderungslistenern:

  • Die Syntax ist grausam, da Browser sie von Haus aus nicht unterstützen. Ja, es gibt Proxys, aber sie sind nicht in allen Fällen semantisch korrekt, und natürlich gibt es in alten Browsern keine Proxys. Die Quintessenz ist, dass Sie bei der Dirty-Prüfung POJO ausführen können, während KnockoutJS und Backbone.js Sie zwingen, von ihren Klassen zu erben und über Accessoren auf Ihre Daten zuzugreifen.
  • Koaleszenz ändern. Angenommen, Sie haben eine Reihe von Elementen. Angenommen, Sie möchten Elemente zu einem Array hinzufügen, während Sie eine Schleife ausführen, um jedes Mal, wenn Sie Elemente hinzufügen, Ereignisse bei Änderung auszulösen, wodurch die Benutzeroberfläche gerendert wird. Dies ist sehr schlecht für die Leistung. Sie möchten, dass die Benutzeroberfläche am Ende nur einmal aktualisiert wird. Die Änderungsereignisse sind zu feinkörnig.
  • Änderungslistener feuern sofort auf einen Setter, was ein Problem darstellt, da der Änderungslistener Daten weiter ändern kann, wodurch mehr Änderungsereignisse ausgelöst werden. Dies ist schlecht, da auf Ihrem Stack möglicherweise mehrere Änderungsereignisse gleichzeitig stattfinden. Angenommen, Sie haben zwei Arrays, die aus irgendeinem Grund synchronisiert werden müssen. Sie können nur das eine oder das andere hinzufügen, aber jedes Mal, wenn Sie hinzufügen, wird ein Änderungsereignis ausgelöst, das nun eine inkonsistente Sicht auf die Welt bietet. Dies ist ein sehr ähnliches Problem wie das Sperren von Threads, das durch JavaScript vermieden wird, da jeder Rückruf exklusiv und vollständig ausgeführt wird. Änderungsereignisse unterbrechen dies, da Setter weitreichende Konsequenzen haben können, die nicht beabsichtigt und nicht offensichtlich sind, was das Thread-Problem erneut verursacht. Es stellt sich heraus, dass Sie die Ausführung des Listeners verzögern und sicherstellen möchten, dass jeweils nur ein Listener ausgeführt wird. Daher kann jeder Code Daten ändern, und es ist bekannt, dass währenddessen kein anderer Code ausgeführt wird .

Was ist mit der Leistung?

Es scheint also, dass wir langsam sind, da die Dirty-Checks ineffizient sind. Hier müssen wir uns reelle Zahlen ansehen und nicht nur theoretische Argumente haben, sondern zunächst einige Einschränkungen definieren.

Menschen sind:

  • Langsam - Alles, was schneller als 50 ms ist, ist für den Menschen nicht wahrnehmbar und kann daher als "augenblicklich" betrachtet werden.

  • Begrenzt - Sie können einem Menschen nicht mehr als ungefähr 2000 Informationen auf einer einzigen Seite anzeigen. Mehr als das ist eine wirklich schlechte Benutzeroberfläche, und die Menschen können dies sowieso nicht verarbeiten.

Die eigentliche Frage lautet also: Wie viele Vergleiche können Sie mit einem Browser in 50 ms durchführen? Dies ist eine schwer zu beantwortende Frage, da viele Faktoren ins Spiel kommen, aber hier ist ein Testfall: http://jsperf.com/angularjs-digest/6 was 10.000 Beobachter schafft. Auf einem modernen Browser dauert dies knapp 6 ms. Bei Internet Explorer 8 dauert es ungefähr 40 ms. Wie Sie sehen, ist dies heutzutage auch bei langsamen Browsern kein Problem. Es gibt eine Einschränkung: Die Vergleiche müssen einfach sein, um in das Zeitlimit zu passen ... Leider ist es viel zu einfach, einen langsamen Vergleich in AngularJS einzufügen, sodass es einfach ist, langsame Anwendungen zu erstellen, wenn Sie nicht wissen, was Sie tun sind dabei. Wir hoffen jedoch, eine Antwort zu erhalten, indem wir ein Instrumentierungsmodul bereitstellen, das Ihnen zeigt, welche Vergleiche langsam sind.

Es stellt sich heraus, dass Videospiele und GPUs den Dirty-Checking-Ansatz verwenden, insbesondere weil er konsistent ist. Solange die Monitoraktualisierungsrate überschritten wird (in der Regel 50-60 Hz oder alle 16,6-20 ms), ist jede Performance eine Verschwendung. Sie sollten also besser mehr Material zeichnen, als eine höhere FPS zu erzielen.

2729
Misko Hevery

Misko hat bereits eine hervorragende Beschreibung der Funktionsweise der Datenbindungen gegeben, aber ich möchte meine Ansicht zum Leistungsproblem bei der Datenbindung hinzufügen.

Wie Misko feststellte, treten bei etwa 2000 Bindungen Probleme auf, aber eine Seite sollte ohnehin nicht mehr als 2000 Informationen enthalten. Dies mag zutreffen, aber nicht jede Datenbindung ist für den Benutzer sichtbar. Sobald Sie damit beginnen, ein Widget oder ein Datenraster mit bidirektionaler Bindung zu erstellen, können Sie leicht 2000 Bindungen treffen, ohne eine schlechte UX zu haben.

Stellen Sie sich beispielsweise ein Kombinationsfeld vor, in das Sie Text eingeben können, um die verfügbaren Optionen zu filtern. Diese Art der Steuerung kann bis zu 150 Elemente enthalten und dennoch sehr gut verwendbar sein. Wenn es eine zusätzliche Funktion hat (zum Beispiel eine bestimmte Klasse für die aktuell ausgewählte Option), erhalten Sie 3-5 Bindungen pro Option. Fügen Sie drei dieser Widgets auf eine Seite ein (z. B. eines zur Auswahl eines Landes, das andere zur Auswahl einer Stadt in diesem Land und das dritte zur Auswahl eines Hotels), und Sie befinden sich bereits in einem Bereich zwischen 1000 und 2000 Bindungen.

Oder betrachten Sie ein Datenraster in einer Unternehmens-Webanwendung. 50 Zeilen pro Seite sind nicht unangemessen, von denen jede 10-20 Spalten haben könnte. Wenn Sie dies mit ng-repeats erstellen und/oder Informationen in einigen Zellen haben, die einige Bindungen verwenden, nähern Sie sich möglicherweise nur mit diesem Raster 2000 Bindungen.

Ich finde, dass dies ein riesiges Problem ist, wenn ich mit AngularJS arbeite, und die einzige Lösung, die ich bisher finden konnte, ist, Widgets ohne bidirektionale Bindung zu konstruieren, anstatt ngOnce zu verwenden und die Registrierung aufzuheben Beobachter und ähnliche Tricks oder Konstruktionsanweisungen, die das DOM mit jQuery- und DOM-Manipulation erstellen. Ich habe das Gefühl, dass dies den Zweck der Verwendung von Angular zunichte macht.

Ich würde gerne Vorschläge zu anderen Möglichkeiten hören, um damit umzugehen, aber dann sollte ich vielleicht meine eigene Frage schreiben. Ich wollte das in einen Kommentar schreiben, aber es stellte sich heraus, dass es dafür viel zu lang war ...

TL; DR
Die Datenbindung kann bei komplexen Seiten zu Leistungsproblemen führen.

318
MW.

Durch fehlerhaftes Prüfen des Objekts $scope

Angular verwaltet eine einfache array Anzahl von Beobachtern in den $scope Objekten. Wenn Sie einen $scope überprüfen, werden Sie feststellen, dass dieser array mit dem Namen $$watchers enthält.

Jeder Beobachter ist ein object, das unter anderem enthält

  1. Ein Ausdruck, den der Beobachter überwacht. Dies könnte nur ein attribute Name sein oder etwas komplizierteres.
  2. Ein letzter bekannter Wert des Ausdrucks. Dies kann mit dem aktuell berechneten Wert des Ausdrucks verglichen werden. Wenn sich die Werte unterscheiden, löst der Beobachter die Funktion aus und markiert den $scope als verschmutzt.
  3. Eine Funktion, die ausgeführt wird, wenn der Watcher verschmutzt ist.

Wie Beobachter definiert sind

Es gibt viele verschiedene Möglichkeiten, einen Beobachter in AngularJS zu definieren.

  • Sie können $watch und attribute in $scope explizit eingeben.

    $scope.$watch('person.username', validateUnique);
    
  • Sie können eine {{}} -Interpolation in Ihre Vorlage einfügen (für den aktuellen $scope wird ein Watcher erstellt).

    <p>username: {{person.username}}</p>
    
  • Sie können eine Anweisung wie ng-model anfordern, um den Watcher für Sie zu definieren.

    <input ng-model="person.username" />
    

Der Zyklus $digest prüft alle Beobachter auf ihren letzten Wert

Wenn wir über die normalen Kanäle (ng-model, ng-repeat usw.) mit AngularJS interagieren, wird durch die Direktive ein Digest-Zyklus ausgelöst.

Ein Digest-Zyklus ist ein tiefes Durchlaufen von $scope und all seinen Kindern. Für jeden $scopeobject iterieren wir über seinen $$watchersarray und werten alle Ausdrücke aus. Wenn sich der neue Ausdruckswert vom letzten bekannten Wert unterscheidet, wird die Funktion des Beobachters aufgerufen. Diese Funktion kann einen Teil des DOM neu kompilieren, einen Wert für $scope neu berechnen, ein AJAXrequest auslösen, was immer Sie tun müssen.

Jeder Gültigkeitsbereich wird durchlaufen und jeder Überwachungsausdruck wird ausgewertet und mit dem letzten Wert verglichen.

Wenn ein Beobachter ausgelöst wird, ist der $scope verschmutzt

Wenn ein Beobachter ausgelöst wird, weiß die App, dass sich etwas geändert hat, und der $scope wird als fehlerhaft markiert.

Watcher-Funktionen können andere Attribute in $scope oder in einem übergeordneten $scope ändern. Wenn eine $watcher -Funktion ausgelöst wurde, können wir nicht garantieren, dass unsere anderen $scopes noch sauber sind, und führen den gesamten Digest-Zyklus erneut aus.

Dies liegt daran, dass AngularJS über eine bidirektionale Bindung verfügt, sodass Daten wieder in den $scope -Baum übertragen werden können. Möglicherweise ändern wir einen Wert für einen höheren $scope, der bereits verdaut wurde. Vielleicht ändern wir einen Wert für den $rootScope.

Wenn der $digest verschmutzt ist, führen wir den gesamten $digest -Zyklus erneut aus

Wir durchlaufen den $digest -Zyklus kontinuierlich, bis entweder der Digest-Zyklus sauber ist (alle $watch -Ausdrücke haben denselben Wert wie im vorherigen Zyklus), oder wir erreichen das Digest-Limit. Standardmäßig ist dieses Limit auf 10 festgelegt.

Wenn wir das Digest-Limit erreichen, wird AngularJS einen Fehler in der Konsole auslösen:

10 $digest() iterations reached. Aborting!

Die Verdauung schont den Computer, aber den Entwickler

Wie Sie sehen, überprüft AngularJS jedes Mal, wenn sich etwas in einer AngularJS-App ändert, jeden einzelnen Beobachter in der $scope -Hierarchie, um zu sehen, wie er reagieren soll. Für einen Entwickler ist dies ein enormer Produktivitätsvorteil, da Sie jetzt fast keinen Verdrahtungscode schreiben müssen. AngularJS wird nur feststellen, ob sich ein Wert geändert hat, und den Rest der App mit der Änderung in Einklang bringen.

Aus Sicht der Maschine ist dies jedoch ineffizient und verlangsamt unsere App, wenn wir zu viele Beobachter erstellen. Misko hat eine Zahl von ungefähr 4000 Beobachtern angegeben, bevor sich Ihre App in älteren Browsern langsam anfühlt.

Diese Grenze ist leicht zu erreichen, wenn Sie ng-repeat über einen großen JSONarray zum Beispiel. Sie können dem entgegenwirken, indem Sie Funktionen wie die einmalige Bindung verwenden, um eine Vorlage zu kompilieren, ohne Beobachter zu erstellen.

So vermeiden Sie, dass zu viele Beobachter erstellt werden

Jedes Mal, wenn Ihr Benutzer mit Ihrer App interagiert, wird jeder einzelne Beobachter in Ihrer App mindestens einmal bewertet. Ein großer Teil der Optimierung einer AngularJS-App besteht darin, die Anzahl der Beobachter in Ihrem $scope -Baum zu verringern. Eine einfache Möglichkeit, dies zu tun, ist die einmalige Bindung .

Wenn Sie Daten haben, die sich selten ändern, können Sie diese nur einmal mithilfe der :: -Syntax binden.

<p>{{::person.username}}</p>

oder

<p ng-bind="::person.username"></p>

Die Bindung wird nur ausgelöst, wenn die enthaltene Vorlage gerendert und die Daten in $scope geladen werden.

Dies ist besonders wichtig, wenn Sie einen ng-repeat mit vielen Elementen haben.

<div ng-repeat="person in people track by username">
  {{::person.username}}
</div>
154
superluminary

Das ist mein Grundverständnis. Es kann gut falsch sein!

  1. Elemente werden überwacht, indem eine Funktion (die das zu überwachende Objekt zurückgibt) an die $watch -Methode übergeben wird.
  2. Änderungen an überwachten Objekten müssen innerhalb eines Codeblocks vorgenommen werden, der von der $apply -Methode umschlossen wird.
  3. Am Ende des $apply wird die $digest -Methode aufgerufen, die jede der Uhren durchläuft und prüft, ob sie sich seit der letzten Ausführung des $digest geändert haben.
  4. Wenn Änderungen gefunden werden, wird der Digest erneut aufgerufen, bis sich alle Änderungen stabilisiert haben.

In der normalen Entwicklung weist die Datenbindungssyntax im HTML den AngularJS-Compiler an, die Watches für Sie zu erstellen, und die Controller-Methoden werden bereits in $apply ausgeführt. Für den Anwendungsentwickler ist also alles transparent.

80
Pete BD

Ich habe mich selbst eine Weile gefragt. Wie bemerkt AngularJS ohne Setter Änderungen am $scope -Objekt? Befragt es sie?

Tatsächlich bewirkt es Folgendes: Jeder "normale" Ort, an dem Sie das Modell ändern, wurde bereits aus den Eingeweiden von AngularJS aufgerufen, sodass $apply automatisch für Sie aufgerufen wird, nachdem der Code ausgeführt wurde. Angenommen, Ihr Controller verfügt über eine Methode, die an einem Element mit ng-click verknüpft ist. Da AngularJS den Aufruf dieser Methode für Sie verkabelt, besteht die Möglichkeit, an der entsprechenden Stelle einen $apply auszuführen. Ebenso werden Ausdrücke, die direkt in den Ansichten angezeigt werden, von AngularJS ausgeführt, sodass der $apply ausgeführt wird.

Wenn es in der Dokumentation darum geht, $apply manuell für Code aufrufen zu müssen außerhalb von AngularJS, dann handelt es sich um Code, der beim Ausführen nicht von AngularJS stammt. sich in der Aufrufliste.

61
jpsimons

Mit Bildern erklären:

Datenbindung benötigt ein Mapping

Die Referenz im Gültigkeitsbereich ist nicht genau die Referenz in der Vorlage. Wenn Sie zwei Objekte miteinander verbinden, benötigen Sie ein drittes Objekt, das das erste abhört und das andere ändert.

enter image description here

Wenn Sie hier den <input> ändern, berühren Sie die Datenreferenz 3 . Und der klassische Datenbindungsmechanismus ändert data-ref4 . Wie bewegen sich die anderen {{data}} Ausdrücke?

Ereignisse führen zu $ ​​digest ()

enter image description here

Angular behält ein oldValue und ein newValue jeder Bindung bei. Und nach jedem Angular-Ereignis überprüft die berühmte $digest() -Schleife die WatchList, um festzustellen, ob sich etwas geändert hat. Diese Winkelereignisse sind ng-click, ng-change, $http abgeschlossen ... Die $digest() wird so lange wiederholt, wie oldValue unterscheidet sich von newValue.

In der vorherigen Abbildung wird festgestellt, dass sich Datenreferenz1 und Datenreferenz2 geändert haben.

Schlussfolgerungen

Es ist ein bisschen wie das Ei und das Huhn. Man weiß nie, wer anfängt, aber hoffentlich funktioniert es die meiste Zeit wie erwartet.

Der andere Punkt ist, dass Sie leicht die Auswirkungen einer einfachen Bindung auf den Speicher und die CPU verstehen können. Hoffentlich sind Desktops fett genug, um damit umzugehen. Handys sind nicht so stark.

32
Nicolas Zozol

Offensichtlich findet keine periodische Überprüfung von Scope statt, ob Änderungen an den damit verbundenen Objekten vorliegen. Nicht alle Objekte, die an den Bereich angehängt sind, werden überwacht. Scope verwaltet prototypisch ein $$ watchers. Scope durchläuft diesen $$watchers nur, wenn $digest aufgerufen wird.

Angular fügt einen Beobachter zu den $$ Beobachtern für jeden von diesen hinzu

  1. {{expression}} - In Ihren Vorlagen (und überall dort, wo es einen Ausdruck gibt) oder wenn wir ein ng-Modell definieren.
  2. $ scope. $ watch (‘expression/function’) - In Ihrem JavaScript können wir einfach ein scope-Objekt anhängen, damit angular es überwacht.

$ watch Funktion nimmt drei Parameter auf:

  1. Die erste ist eine Watcher-Funktion, die nur das Objekt zurückgibt, oder wir können einfach einen Ausdruck hinzufügen.

  2. Die zweite Funktion ist eine Listener-Funktion, die aufgerufen wird, wenn sich das Objekt ändert. Alle Dinge wie DOM-Änderungen werden in dieser Funktion implementiert.

  3. Der dritte ist ein optionaler Parameter, der einen Booleschen Wert enthält. Wenn es wahr ist, beobachtet angular tief das Objekt und wenn es falsch ist, beobachtetAngular nur eine Referenz auf das Objekt. Die grobe Implementierung von $ watch sieht so aus

Scope.prototype.$watch = function(watchFn, listenerFn) {
   var watcher = {
       watchFn: watchFn,
       listenerFn: listenerFn || function() { },
       last: initWatchVal  // initWatchVal is typically undefined
   };
   this.$$watchers.Push(watcher); // pushing the Watcher Object to Watchers  
};

Es gibt eine interessante Sache in Angular namens Digest Cycle. Der $ digest-Zyklus startet als Ergebnis eines Aufrufs von $ scope. $ Digest (). Angenommen, Sie ändern ein $ scope-Modell in einer Handlerfunktion mit der Anweisung ng-click. In diesem Fall löst AngularJS durch Aufrufen von $ digest () automatisch einen $ digest-Zyklus aus. Zusätzlich zu ng-click gibt es mehrere andere integrierte Direktiven/Dienste, mit denen Sie Modelle ändern können (z. B. ng-model, $ timeout usw.). und automatisch einen $ digest-Zyklus auslösen. Die grobe Implementierung von $ digest sieht so aus.

Scope.prototype.$digest = function() {
      var dirty;
      do {
          dirty = this.$$digestOnce();
      } while (dirty);
}
Scope.prototype.$$digestOnce = function() {
   var self = this;
   var newValue, oldValue, dirty;
   _.forEach(this.$$watchers, function(watcher) {
          newValue = watcher.watchFn(self);
          oldValue = watcher.last;   // It just remembers the last value for dirty checking
          if (newValue !== oldValue) { //Dirty checking of References 
   // For Deep checking the object , code of Value     
   // based checking of Object should be implemented here
             watcher.last = newValue;
             watcher.listenerFn(newValue,
                  (oldValue === initWatchVal ? newValue : oldValue),
                   self);
          dirty = true;
          }
     });
   return dirty;
 };

Wenn wir die setTimeout () - Funktion von JavaScript verwenden, um ein Bereichsmodell zu aktualisieren, kann Angular nicht wissen, was Sie möglicherweise ändern. In diesem Fall liegt es in unserer Verantwortung, $ apply () manuell aufzurufen, wodurch ein $ digest-Zyklus ausgelöst wird. Wenn Sie eine Direktive haben, die einen DOM-Ereignis-Listener einrichtet und einige Modelle in der Handler-Funktion ändert, müssen Sie $ apply () aufrufen, um sicherzustellen, dass die Änderungen wirksam werden. Die große Idee von $ apply ist, dass wir Code ausführen können, der Angular nicht kennt. Dieser Code kann möglicherweise noch Änderungen am Gültigkeitsbereich bewirken. Wenn wir diesen Code in $ apply einschließen, wird $ digest () aufgerufen. Grobe Implementierung von $ apply ().

Scope.prototype.$apply = function(expr) {
       try {
         return this.$eval(expr); //Evaluating code in the context of Scope
       } finally {
         this.$digest();
       }
};
22

AngularJS verwaltet den Datenbindungsmechanismus mithilfe von drei leistungsstarken Funktionen: $ watch () , $ digest () und $ apply () . In den meisten Fällen ruft AngularJS $ scope. $ Watch () und $ scope. $ Digest () auf. In einigen Fällen müssen Sie diese Funktionen jedoch manuell aufrufen, um eine Aktualisierung mit neuen Werten durchzuführen.

$ watch () : -

Diese Funktion wird verwendet, um Änderungen in einer Variablen im Bereich $ zu beobachten. Es akzeptiert drei Parameter: Ausdruck, Listener und Gleichheitsobjekt, wobei Listener und Gleichheitsobjekt optionale Parameter sind.

$ digest () -

Diese Funktion durchläuft alle Überwachungen im $ scope-Objekt und seinen untergeordneten $ scope-Objekten
(falls vorhanden). Wenn $ digest () über die Watches iteriert, wird geprüft, ob sich der Wert des Ausdrucks geändert hat. Wenn sich der Wert geändert hat, ruft AngularJS den Listener mit neuem und altem Wert auf. Die Funktion $ digest () wird immer dann aufgerufen, wenn AngularJS dies für erforderlich hält. Zum Beispiel nach einem Klick auf eine Schaltfläche oder nach einem AJAX -Aufruf. Es kann vorkommen, dass AngularJS die Funktion $ digest () nicht für Sie aufruft. In diesem Fall müssen Sie es selbst nennen.

$ apply () -

Angular do aktualisiert automatisch nur die Modelländerungen, die sich im AngularJS-Kontext befinden. Wenn Sie ein Modell außerhalb des Angular -Kontexts ändern (z. B. Browser-DOM-Ereignisse, setTimeout, XHR oder Bibliotheken von Drittanbietern), müssen Sie Angular über die Änderungen durch Aufrufen informieren $ apply () manuell. Wenn der Funktionsaufruf $ apply () beendet ist, ruft AngularJS intern $ digest () auf, sodass alle Datenbindungen aktualisiert werden.

15
Bharath Kumar

Es kam vor, dass ich ein Datenmodell einer Person mit einem Formular verknüpfen musste, was ich tat, war eine direkte Zuordnung der Daten mit dem Formular.

Zum Beispiel, wenn das Modell etwas hatte wie:

$scope.model.people.name

Die Steuereingabe des Formulars:

<input type="text" name="namePeople" model="model.people.name">

Auf diese Weise wird der Wert des Objektcontrollers automatisch in die Ansicht übernommen.

Ein Beispiel für die Aktualisierung des Modells anhand von Serverdaten ist, dass Sie eine Liste der mit dieser Ansicht verknüpften Kolonien und Städte anfordern und standardmäßig den ersten Wert mit dem Benutzer festlegen. Und das habe ich sehr gut gemacht, was passiert ist, dass angularJS manchmal ein paar Sekunden dauert, um das Modell zu aktualisieren. Dazu können Sie einen Drehknopf setzen, während die Daten angezeigt werden.

7
gartox
  1. Die unidirektionale Datenbindung ist ein Ansatz, bei dem ein Wert aus dem Datenmodell entnommen und in ein HTML-Element eingefügt wird. Es gibt keine Möglichkeit, das Modell über die Ansicht zu aktualisieren. Es wird in klassischen Template-Systemen eingesetzt. Diese Systeme binden Daten nur in eine Richtung.

  2. Datenbindung in Angular Apps ist die automatische Synchronisierung von Daten zwischen den Modell- und Ansichtskomponenten.

Mit der Datenbindung können Sie das Modell als eine Quelle der Wahrheit in Ihrer Anwendung behandeln. Die Ansicht ist zu jeder Zeit eine Projektion des Modells. Wenn das Modell geändert wird, spiegelt die Ansicht die Änderung wider und umgekehrt.

6

AngularJs unterstützt Zwei-Wege-Datenbindung.
Bedeutet, dass Sie auf Daten zugreifen können Ansicht -> Controller & Controller -> Ansicht

Zum Beispiel

1)

// If $scope have some value in Controller. 
$scope.name = "Peter";

// HTML
<div> {{ name }} </div>

O/P

Peter

Sie können Daten in ng-model wie folgt binden: -
2)

<input ng-model="name" />

<div> {{ name }} </div>

Hier im obigen Beispiel wird, was auch immer der Benutzer eingibt, es im Tag <div> angezeigt.

Wenn Sie Eingaben von HTML an den Controller binden möchten: -
)

<form name="myForm" ng-submit="registration()">
   <label> Name </lbel>
   <input ng-model="name" />
</form>

Hier, wenn Sie den Eingang name in der Steuerung verwenden möchten,

$scope.name = {};

$scope.registration = function() {
   console.log("You will get the name here ", $scope.name);
};

ng-model bindet unsere Sichtweise und gibt sie als Ausdruck {{ }} wieder.
ng-model sind die Daten, die dem Benutzer in der Ansicht angezeigt werden und mit denen der Benutzer interagiert.
So ist es einfach, Daten in AngularJs zu binden.

5
ojus kulkarni

Hier ist ein Beispiel für die Datenbindung mit AngularJS über ein Eingabefeld. Ich werde es später erklären

HTML-Code

<div ng-app="myApp" ng-controller="myCtrl" class="formInput">
     <input type="text" ng-model="watchInput" Placeholder="type something"/>
     <p>{{watchInput}}</p> 
</div>

AngularJS-Code

myApp = angular.module ("myApp", []);
myApp.controller("myCtrl", ["$scope", function($scope){
  //Your Controller code goes here
}]);

Wie Sie im obigen Beispiel sehen können, verwendet AngularJS ng-model, um zu hören und zu beobachten, was mit HTML-Elementen geschieht, insbesondere mit input -Feldern. Wenn etwas passiert, tu etwas. In unserem Fall ist ng-model mit der Schnurrbartnotation {{}} an unsere Ansicht gebunden. Was auch immer in das Eingabefeld eingegeben wird, wird sofort auf dem Bildschirm angezeigt. Und das ist das Schöne an der Datenbindung mit AngularJS in seiner einfachsten Form.

Hoffe das hilft.

Ein funktionierendes Beispiel finden Sie hier unter Codepen

5
AllJs

Angular.js erstellt einen Beobachter für jedes Modell, das wir in der Ansicht erstellen. Jedes Mal, wenn ein Modell geändert wird, wird eine "ng-dirty" -Klasse an das Modell angehängt, sodass der Beobachter alle Modelle mit der Klasse "ng-dirty" beobachtet und ihre Werte im Controller aktualisiert und umgekehrt.

4

Datenbindung:

Was ist Datenbindung?

Immer wenn der Benutzer die Daten in der Ansicht ändert, erfolgt eine Aktualisierung dieser Änderung im Bereichsmodell und umgekehrt.

Wie ist es möglich?

Kurze Antwort: Mit Hilfe des Verdauungszyklus.

Description: Angular js setzt den Watcher auf das Scope-Modell, das die Listener-Funktion auslöst, wenn sich das Modell ändert.

$scope.$watch('modelVar' , function(newValue,oldValue){

// Dom Update Code mit neuem Wert

});

Also wann und wie wird die Watcher-Funktion aufgerufen?

Die Watcher-Funktion wird als Teil des Digest-Zyklus aufgerufen.

Der Digest-Zyklus wird automatisch als Teil von angular js aufgerufen, die in Direktiven/Diensten wie ng-model, ng-bind, $ timeout, ng-click und anderen enthalten sind, mit denen Sie den Digest-Zyklus auslösen können.

Digest-Cycle-Funktion:

$scope.$digest() -> digest cycle against the current scope.
$scope.$apply() -> digest cycle against the parent scope 

i.e$rootScope.$apply()

Hinweis: $ apply () ist gleich $ rootScope. $ Digest () bedeutet, dass die Dirty-Prüfung direkt vom Root- oder Top-Bereich oder vom übergeordneten Bereich bis zu allen untergeordneten Bereichen in der Anwendung angular js beginnt .

Die oben genannten Funktionen funktionieren in den Browsern IE für die genannten Versionen auch nur, indem Sie sicherstellen, dass Ihre Anwendung angular js-Anwendung ist .

Danke.

3
Dhana