Frage

Wie funktioniert die Datenbindung im AngularJS Rahmen?

Ich habe keine technischen Details dazu gefunden ihre Website.Es ist mehr oder weniger klar, wie es funktioniert, wenn Daten von der Ansicht an das Modell weitergegeben werden.Aber wie verfolgt AngularJS Änderungen an Modelleigenschaften ohne Setter und Getter?

Ich habe festgestellt, dass es welche gibt JavaScript-Beobachter das kann diese Arbeit machen.Aber sie werden nicht unterstützt Internet Explorer 6 Und Internet Explorer 7.Woher weiß AngularJS also, dass ich beispielsweise Folgendes geändert und diese Änderung in einer Ansicht widergespiegelt habe?

myobject.myproperty="new value";
War es hilfreich?

Lösung

AngularJS merkt sich den Wert und vergleicht ihn mit einem vorherigen Wert.Dies ist ein grundlegendes Dirty-Checking.Wenn sich der Wert ändert, wird das Änderungsereignis ausgelöst.

Der $apply() -Methode, die Sie aufrufen, wenn Sie von einer Nicht-AngularJS-Welt in eine AngularJS-Welt wechseln, ruft auf $digest().Ein Digest ist einfach nur eine schmutzige Prüfung.Es funktioniert auf allen Browsern und ist völlig vorhersehbar.

Um Dirty-Checking (AngularJS) und Change-Listener zu vergleichen (KnockoutJS Und Backbone.js):Während Dirty-Checking einfach und sogar ineffizient erscheinen mag (darauf werde ich später eingehen), stellt sich heraus, dass es immer semantisch korrekt ist, während Change-Listener viele seltsame Eckfälle haben und Dinge wie Abhängigkeitsverfolgung benötigen, um es besser zu machen semantisch korrekt.Die KnockoutJS-Abhängigkeitsverfolgung ist eine clevere Funktion für ein Problem, das AngularJS nicht hat.

Probleme mit Change-Listenern:

  • Die Syntax ist grauenhaft, da Browser sie nicht nativ unterstützen.Ja, es gibt Proxys, diese sind jedoch nicht in allen Fällen semantisch korrekt, und natürlich gibt es in alten Browsern keine Proxys.Die Quintessenz ist, dass Dirty-Checking Ihnen dies ermöglicht POJO, wohingegen KnockoutJS und Backbone.js Sie dazu zwingen, von ihren Klassen zu erben und über Accessoren auf Ihre Daten zuzugreifen.
  • Zusammenwachsen verändern.Angenommen, Sie haben eine Reihe von Elementen.Angenommen, Sie möchten einem Array Elemente hinzufügen, während Sie in einer Schleife hinzufügen, um jedes Mal, wenn Sie hinzufügen, Ereignisse bei Änderungen auszulösen, wodurch die Benutzeroberfläche gerendert wird.Das ist sehr schlecht für die Leistung.Sie möchten die Benutzeroberfläche am Ende nur einmal aktualisieren.Die Änderungsereignisse sind zu feinkörnig.
  • Änderungs-Listener werden sofort auf einen Setter ausgelöst, was ein Problem darstellt, da der Änderungs-Listener weitere Daten ändern kann, was mehr Änderungsereignisse auslöst.Das ist schlecht, da auf Ihrem Stack möglicherweise mehrere Änderungsereignisse gleichzeitig stattfinden.Angenommen, Sie haben zwei Arrays, die aus irgendeinem Grund synchron gehalten werden müssen.Sie können nur das eine oder das andere hinzufügen, aber jedes Mal, wenn Sie etwas hinzufügen, lösen Sie ein Änderungsereignis aus, das nun eine inkonsistente Sicht auf die Welt hat.Dies ist ein sehr ähnliches Problem wie die Thread-Sperre, die JavaScript vermeidet, da jeder Rückruf exklusiv und vollständig ausgeführt wird.Änderungsereignisse machen dies zunichte, 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, sodass jeder Code Daten ändern kann und weiß, dass währenddessen kein anderer Code ausgeführt wird .

Wie sieht es mit der Leistung aus?

Es scheint also, dass wir langsam sind, da Dirty-Checking ineffizient ist.Hier müssen wir uns mit reellen Zahlen befassen und nicht nur mit theoretischen Argumenten, aber lassen Sie uns 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 — Man kann einem Menschen nicht wirklich mehr als etwa 2000 Informationen auf einer einzigen Seite zeigen.Alles darüber hinaus ist eine wirklich schlechte Benutzeroberfläche, und Menschen können das sowieso nicht verarbeiten.

Die eigentliche Frage ist also diese:Wie viele Vergleiche können Sie in einem Browser in 50 ms durchführen?Diese Frage ist schwer zu beantworten, da viele Faktoren eine Rolle spielen, aber hier ist ein Testfall: http://jsperf.com/angularjs-digest/6 was 10.000 Zuschauer schafft.In einem modernen Browser dauert dies knapp 6 ms.An Internet Explorer 8 es dauert etwa 40 ms.Wie Sie sehen, ist dies heutzutage selbst bei langsamen Browsern kein Problem mehr.Es gibt eine Einschränkung:Die Vergleiche müssen einfach sein, damit sie in das Zeitlimit passen ...Leider ist es viel zu einfach, einen langsamen Vergleich in AngularJS einzufügen, sodass es einfach ist, langsame Anwendungen zu erstellen, wenn man nicht weiß, was man tut.Wir hoffen jedoch, eine Antwort zu erhalten, indem wir ein Instrumentierungsmodul bereitstellen, das Ihnen zeigt, welche Vergleiche langsamer sind.

Es stellt sich heraus, dass Videospiele und GPUs den Dirty-Checking-Ansatz verwenden, insbesondere weil er konsistent ist.Solange sie die Bildwiederholfrequenz des Monitors überschreiten (normalerweise 50–60 Hz oder alle 16,6–20 ms), ist jede darüber hinausgehende Leistung eine Verschwendung. Es ist also besser, mehr Inhalte abzurufen, als die FPS zu erhöhen.

Andere Tipps

Misko gab bereits eine hervorragende Beschreibung der Funktionsweise der Datenbindungen, aber ich möchte mit der Datenbindung meine Ansicht auf das Performance-Problem hinzufügen.

Wie Misko erklärt, sind um rund 2000 Bindungen, in denen Sie Probleme sehen, Probleme, aber Sie sollten trotzdem keine mehr als 2000 Informationen auf einer Seite haben. Dies kann true sein, aber nicht jede Datenbindung ist für den Benutzer sichtbar. Sobald Sie mit dem Aufbau eines Widgets oder eines Datengitters mit zwei Wege-Bindung aufgebaut haben, können Sie einfach einfach 2000 Bindungen treffen, ohne einen schlechten UX zu haben.

Betrachten Sie beispielsweise ein Kombinationsfeld, in dem Sie Text eingeben können, um die verfügbaren Optionen zu filtern. Diese Art der Kontrolle könnte ~ 150 Artikel haben und sind immer noch sehr nutzbar. Wenn es ein zusätzliches Funktionen hat (zum Beispiel eine bestimmte Klasse auf der aktuell ausgewählten Option), erhalten Sie mit 3-5 Bindungen pro Option. Setzen Sie drei dieser Widgets auf eine Seite (z. B. einer, um ein Land auszuwählen, das andere, um eine Stadt in dem genannten Land auszuwählen, und der dritte, um ein Hotel auszuwählen) und Sie sind irgendwo zwischen 1000 und 2000 Bindungen bereits.

oder betrachten Sie ein Datengitter in einer Unternehmens-Webanwendung. 50 Zeilen pro Seite sind nicht unvernünftig, von denen sich jeweils 10-20 Säulen haben könnten. Wenn Sie dies mit NG-Repeats erstellen, und / oder Informationen in einigen Zellen haben, die einige Bindungen verwenden, können Sie sich 2000 Bindungen mit diesem Gitter allein nähern.

Ich finde, dass dies ein riesiges Problem ist, wenn Sie mit Angularjs arbeiten, und die einzige Lösung, die ich bisher finden konnte, besteht darin, Widgets ohne Zwei-Wege-Bindung zu erstellen, anstatt zwei Wege zu verwenden Ngonce, deregisternde Beobachter und ähnliche Tricks oder Konstruktionsrichtlinien, die den Dom mit jQuery- und Dom Manipulation bauen. Ich glaube, dies besiegt den Zweck der Verwendung von Winkel an erster Stelle.

Ich würde gerne Vorschläge auf andere Weise hören, um damit umzugehen, aber dann sollte ich vielleicht meine eigene Frage schreiben. Ich wollte das in einen Kommentar legen, aber es stellte sich heraus, dass es zu lange zu lange ist ...

tl; dr
Die Datenbindung kann Leistungsprobleme auf komplexen Seiten verursachen.

Durch schmutziges Überprüfen der $scope Objekt

Angular behält eine einfache bei array von Beobachtern in der $scope Objekte.Wenn Sie welche inspizieren $scope Sie werden feststellen, dass es eine enthält array angerufen $$watchers.

Jeder Beobachter ist ein object das enthält unter anderem

  1. Ein Ausdruck, den der Beobachter überwacht.Dies könnte nur ein sein attribute Name oder etwas Komplizierteres.
  2. Ein letzter bekannter Wert des Ausdrucks.Dies kann anhand des aktuell berechneten Werts des Ausdrucks überprüft werden.Bei unterschiedlichen Werten löst der Beobachter die Funktion aus und markiert die $scope so dreckig.
  3. Eine Funktion, die ausgeführt wird, wenn der Watcher schmutzig ist.

Wie Beobachter definiert sind

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

  • Sie können explizit $watch ein attribute An $scope.

    $scope.$watch('person.username', validateUnique);
    
  • Sie können eine platzieren {{}} Interpolation in Ihrer Vorlage (ein Watcher wird für Sie auf dem aktuellen Stand erstellt $scope).

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

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

Der $digest Der Zyklus vergleicht alle Beobachter mit ihrem letzten Wert

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

Ein Verdauungszyklus ist ein Tiefendurchquerung von $scope und alle seine Kinder.Für jede $scope object, wir iterieren darüber $$watchers array und bewerten Sie alle Ausdrücke.Wenn der neue Ausdruckswert vom letzten bekannten Wert abweicht, wird die Watcher-Funktion aufgerufen.Diese Funktion kompiliert möglicherweise einen Teil des DOM neu und berechnet einen Wert neu $scope, eine auslösen AJAX request, alles, was Sie brauchen.

Jeder Bereich wird durchlaufen und jeder Überwachungsausdruck ausgewertet und mit dem letzten Wert verglichen.

Wenn ein Watcher ausgelöst wird, wird der $scope ist dreckig

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

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

Dies liegt daran, dass AngularJS über eine bidirektionale Bindung verfügt, sodass Daten wieder nach oben weitergeleitet werden können $scope Baum.Wir können einen Wert auf einen höheren Wert ändern $scope das ist schon verdaut.Vielleicht ändern wir einen Wert auf dem $rootScope.

Wenn die $digest schmutzig ist, führen wir das Ganze aus $digest noch einmal radeln

Wir durchlaufen ständig die $digest Zyklus, bis entweder der Digest-Zyklus sauber erscheint (alle $watch Ausdrücke haben den gleichen Wert wie im vorherigen Zyklus), oder wir erreichen das Digest-Limit.Standardmäßig ist dieser Grenzwert auf 10 eingestellt.

Wenn wir das Digest-Limit erreichen, meldet AngularJS einen Fehler in der Konsole:

10 $digest() iterations reached. Aborting!

Der Digest ist hart für die Maschine, aber schonend für 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 man reagiert.Für einen Entwickler ist dies ein enormer Produktivitätsvorteil, da Sie jetzt fast keinen Verkabelungscode mehr schreiben müssen. AngularJS bemerkt nur, wenn sich ein Wert geändert hat, und sorgt dafür, dass der Rest der App mit der Änderung konsistent ist.

Aus Sicht der Maschine ist dies jedoch äußerst ineffizient und wird unsere App verlangsamen, wenn wir zu viele Beobachter erstellen.Misko hat eine Zahl von etwa 4000 Zuschauern angegeben, bevor sich Ihre App auf älteren Browsern langsam anfühlt.

Diese Grenze ist leicht zu erreichen, wenn Sie ng-repeat über eine große JSON array Zum Beispiel.Sie können dem entgegenwirken, indem Sie Funktionen wie die einmalige Bindung zum Kompilieren einer Vorlage verwenden, 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 Ihrer App zu reduzieren $scope Baum.Eine einfache Möglichkeit, dies zu tun, ist mit einmalig verbindlich.

Wenn Sie Daten haben, die sich selten ändern, können Sie sie nur einmal binden, indem Sie Folgendes verwenden::Syntax, etwa so:

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

oder

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

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

Dies ist besonders wichtig, wenn Sie eine haben ng-repeat mit vielen Artikeln.

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

Das ist mein Grundverständnis.Es könnte durchaus falsch sein!

  1. Die Elemente werden angesehen, indem eine Funktion übergeben wird (um das zu beobachtete Ding zurückzugeben) an die $watch Methode.
  2. Änderungen an beobachteten Elementen müssen innerhalb eines von der Code eingepackten Codes vorgenommen werden $apply Methode.
  3. Am Ende von $apply Die $digest Die Methode wird aufgerufen, die jede der Uhren und Überprüfungen durchläuft, um festzustellen, ob sie sich seit dem letzten Mal geändert haben $digest rannte.
  4. Wenn Änderungen gefunden werden, wird der Digest erneut aufgerufen, bis sich alle Änderungen stabilisiert haben.

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

Ich habe mich das selbst eine Weile gefragt.Wie geht das ohne Setter? AngularJS Beachten Sie Änderungen an der $scope Objekt?Befragt es sie?

Was es tatsächlich tut, ist Folgendes:Jeder „normale“ Ort, an dem Sie das Modell ändern, wurde bereits aus dem Bauch heraus aufgerufen AngularJS, also ruft es automatisch auf $apply für Sie, nachdem Ihr Code ausgeführt wurde.Angenommen, Ihr Controller verfügt über eine Methode, mit der er verbunden ist ng-click auf ein Element.Weil AngularJS Wenn Sie den Aufruf dieser Methode für Sie zusammenstellen, besteht die Möglichkeit, Folgendes zu tun: $apply an der entsprechenden Stelle.Ebenso werden Ausdrücke, die direkt in den Ansichten angezeigt werden, von ausgeführt AngularJS also tut es das $apply.

Wenn in der Dokumentation davon die Rede ist, dass man anrufen muss $apply manuell für Code außerhalb AngularJS, handelt es sich um Code, der, wenn er ausgeführt wird, nicht aus diesem Code stammt AngularJS selbst im Aufrufstapel.

Mit Bildern erklären:

Datenbindung benötigt eine Zuordnung

Die Referenz im Bereich ist nicht genau die Referenz in der Vorlage.Wenn Sie zwei Objekte datenbinden, benötigen Sie ein drittes, das das erste abhört und das andere ändert.

enter image description here

Hier, wenn Sie die ändern <input>, du berührst das Daten-Ref3.Und der klassische Datenbindungsmechanismus wird sich ändern Daten-Ref4.So wie das andere {{data}} Ausdrücke werden sich bewegen?

Ereignisse führen zu $digest()

enter image description here

Angular unterhält a oldValue Und newValue jeder Bindung.Und nach jedem Winkelereignis, die Berühmten $digest() Die Schleife überprüft die WatchList, um festzustellen, ob sich etwas geändert hat.Diese Winkelereignisse Sind ng-click, ng-change, $http vollendet ...Der $digest() wird so lange wie möglich wiederholt oldValue unterscheidet sich von der newValue.

Im vorherigen Bild werden Sie feststellen, dass sich data-ref1 und data-ref2 geändert haben.

Schlussfolgerungen

Es ist ein bisschen wie bei Egg and Chicken.Man weiß nie, wer anfängt, aber hoffentlich funktioniert es die meiste Zeit wie erwartet.

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

Offensichtlich gibt es keine regelmäßige Überprüfung Scope ob sich an den damit verbundenen Objekten etwas ändert.Nicht alle mit dem Scope verbundenen Objekte werden überwacht.Scope unterhält vorbildgetreu a $$Beobachter . Scope iteriert nur dadurch $$watchers Wann $digest wird genannt .

Angular fügt für jeden davon einen Watcher zu den $$watchern hinzu

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

$watch Die Funktion benötigt drei Parameter:

  1. Die erste ist eine Watcher-Funktion, die einfach 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 annimmt.Wenn es wahr ist, überwacht Angular Deep das Objekt, und wenn es falsch ist, führt Angular nur eine Referenzbeobachtung des Objekts durch.Die grobe Implementierung von $watch sieht folgendermaßen 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  
};

In Angular gibt es eine interessante Sache namens Digest Cycle.Der $digest-Zyklus beginnt als Ergebnis eines Aufrufs von $scope.$digest().Angenommen, Sie ändern ein $scope-Modell in einer Handlerfunktion über die ng-click-Direktive.In diesem Fall löst AngularJS automatisch einen $digest-Zyklus aus, indem es $digest() aufruft. Zusätzlich zu ng-click gibt es mehrere andere integrierte Anweisungen/Dienste, mit denen Sie Modelle ändern können (z. B.ng-model, $timeout usw.) und lösen automatisch einen $digest-Zyklus aus.Die grobe Implementierung von $digest sieht folgendermaßen 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 JavaScripts verwenden setTimeout() Wenn Sie die Funktion zum Aktualisieren eines Bereichsmodells verwenden, kann Angular nicht wissen, was Sie möglicherweise ändern.In diesem Fall liegt es in unserer Verantwortung, $apply() manuell aufzurufen, was einen $digest-Zyklus auslöst.Wenn Sie über eine Direktive verfügen, die einen DOM-Ereignis-Listener einrichtet und einige Modelle innerhalb der Handlerfunktion ändert, müssen Sie ebenfalls $apply() aufrufen, um sicherzustellen, dass die Änderungen wirksam werden.Die große Idee von $apply besteht darin, dass wir Code ausführen können, der Angular nicht kennt. Dieser Code kann dennoch Dinge im Bereich ändern.Wenn wir diesen Code in $apply einbinden, kümmert er sich um den Aufruf von $digest().Grobe Implementierung von $apply().

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

Angularjs-Griff-Datenbindungsmechanismus mit Hilfe von drei leistungsstarken Funktionen: $ watch () , $ digest () und $ gilt () . Der größte Teil der Angularjs nennt den $ Scope. $ Uhr () und $ scope. $ Digest (), aber aber In einigen Fällen müssen Sie diese Funktionen möglicherweise manuell anrufen, um mit neuen Werten zu aktualisieren.

$ uhr () : -

Diese Funktion dient zur Beobachtung von Änderungen in einer Variablen auf dem $ Scope. Es akzeptiert drei Parameter: Expression, Listener und Gleichstellungsobjekt, Wo Listener und Gleichstellungsobjekt optionale Parameter sind.

$ digest () -

Diese Funktion itert durch alle Uhren in dem $ Scope-Objekt, und sein Kind $ Scope-Objekte
(wenn es irgendwelche hat). Wenn $ Digest () iteriert Über den Uhren prüft es, ob der Wert des Ausdrucks hat geändert. Wenn sich der Wert geändert hat, ruft Angularjs den Hörer an Neuer Wert und alter Wert. Die Funktion von $ Digest () wird aufgerufen Wann immer Angularjs denkt, ist es notwendig. Zum Beispiel nach einem Knopf Klicken Sie auf oder nach einem Ajax-Anruf. Möglicherweise haben Sie einige Fälle, in denen Angularjs Ruft die $ Digest () -Funktion nicht für Sie an. In diesem Fall müssen Sie nenne es selbst.

$ gilt () -

eckular do auto-magical aktualisiert nur die Modelländerungen, die sich befinden Innerhalb von Angularjs-Kontext. Wenn Sie sich in jedem Modell außerhalb von ändert der Winkelkontext (wie Browser Dom Events, Settimeout, XHR oder Dritter Partybibliotheken), dann müssen Sie die Winkel der Änderungen von informieren $ aufrufen () manuell. Wenn die $ () -Funktionsaufforderung Angularjs ruft $ Digest () intern an, sodass alle Datenbindungen sind aktualisiert.

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

Wenn das Modell beispielsweise so etwas hätte:

$scope.model.people.name

Die Steuereingabe des Formulars:

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

Wenn Sie auf diese Weise den Wert des Objektcontrollers ändern, wird dies automatisch in der Ansicht widergespiegelt.

Ein Beispiel, bei dem ich übergeben habe, dass das Modell anhand von Serverdaten aktualisiert wird, ist, wenn Sie nach einer Postleitzahl fragen und die Postleitzahl basierend auf schriftlichen Angaben eine Liste von Kolonien und Städten lädt, die dieser Ansicht zugeordnet sind, und standardmäßig den ersten Wert mit dem Benutzer festlegen.Und das habe ich sehr gut gemacht, was passiert, ist das angularJS Manchmal dauert es ein paar Sekunden, bis das Modell aktualisiert ist. Dazu können Sie während der Anzeige der Daten einen Spinner setzen.

    .
  1. Die Einwegdatenbindung ist ein Ansatz, bei dem ein Wert aus dem Datenmodell entnommen und in ein HTML-Element eingesetzt wird.Es gibt keine Möglichkeit, das Modell von Sicht zu aktualisieren.Es wird in klassischen Vorlagensystemen verwendet.Diese Systeme binden Daten nur in einer Richtung.

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

  3. Datenbindung können Sie das Modell als Single-Source-of-Wahrheit in Ihrer Anwendung behandeln.Die Ansicht ist jederzeit eine Projektion des Modells.Wenn das Modell geändert wird, spiegelt die Ansicht die Änderung wider und umgekehrt.

Hier ist ein Beispiel für die Datenbindung mit AngularJS unter Verwendung eines Eingabefelds.Ich werde es später erklären

HTML Quelltext

<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, AngularJS Verwendet ng-model um zuzuhören und zu beobachten, was mit HTML-Elementen passiert, insbesondere mit input Felder.Wenn etwas passiert, tun Sie etwas.In unserem Fall, ng-model ist unserer Ansicht nach unter Verwendung der Schnurrbartnotation verbindlich {{}}.Was auch immer in das Eingabefeld eingegeben wird, wird sofort auf dem Bildschirm angezeigt.Und das ist das Schöne an der Datenbindung, nämlich der Verwendung von AngularJS in seiner einfachsten Form.

Hoffe das hilft.

Ein funktionierendes Beispiel finden Sie hierCodepen

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

für ex.

1)

generasacodicetagpre.

o / p

generasacodicetagpre.

Sie können Daten in ng-model binden, z. B.: -
2)

generasacodicetagpre.

Hier in dem obiger Beispiel, welcher Eingangsbenutzer ergibt, wird es im generakoditicetagcode-Tag sichtbar sein.

Wenn Sie die Eingabe von HTML an den Controller binden möchten: -
3)

generasacodicetagpre.

Hier, wenn Sie den Eingabe generationspoDicetagcode in der Steuerung verwenden möchten, dann

generasacodicetagpre.

<div> bindet unsere Ansicht und rendern sie in Expression name.
ng-model ist die Daten, die dem Benutzer in der Ansicht angezeigt und mit dem der Benutzer interagiert.
So ist es einfach, Daten in Angularjs zu binden.

angular.js erstellt einen Watcher für jedes Modell, das wir im Sicht erstellen.Immer wenn ein Modell geändert wird, wird eine "ng-schmutzige" Klasse an das Modell geheilt, sodass der Watcher alle Modelle beobachtet, die über die Klasse "NG-DIRTION" verfügen, und ihre Werte in der Steuerung und umgekehrt aktualisieren.

Datenbindung:

Was ist die Datenbindung?

Wenn der Benutzer die Daten in der Ansicht ändert, tritt eine Aktualisierung dieser Änderung des Geltungsmodells und auf VICEVERSA auf.

wie ist es möglich?

kurze Antwort: Mit Hilfe des Digest-Zyklus.

Beschreibung: Angular JS Legt den Watcher im Bereich Scope-Modell fest, der die Hörerfunktion feuert, wenn sich ein Modell ändern.

generasacodicetagpre.

// dom Update-Code mit neuem Wert

});

Also wann und wie ist die Watcher-Funktion angerufen?

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

Digest-Zyklus wird automatisch aufgerufen, der als Teil von Angular JS in Richtlinien / Dienste wie NG-Modell, NG-Bind, $ Timeout, NG-Click und anderen ausgelöst wird. Dadurch können Sie den Digest-Zyklus auslösen.

Digest-Zyklusfunktion:

generasacodicetagpre.

i.$rootScope.$apply()

Hinweis: $ Apply () ist gleich $ Rootscope. $ digest () Dies bedeutet, dass die verschmutzte Überprüfung direkt von der Wurzel oder oben oder dem übergeordneten Umfang an alle Kinderkopfte in der Winkel-JS-Anwendung beginnt.

Die oben genannten Funktionen funktionieren in den Browsern, dh für die genannten Versionen, auch wenn Sie sicherstellen, dass Ihre Anmeldung die eckige JS-Anwendung ist, was bedeutet, dass Sie die in dem Skript-Tag verwiesene Angularjs-Framework-Skriptdatei verwenden.

danke.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top