Heim >Web-Frontend >js-Tutorial >Wie funktioniert prototypische Vererbung mit bidirektionaler Datenbindung in AngularJS-Bereichen?
Was sind die Nuancen der Scope-Prototyp-/Prototyp-Vererbung in AngularJS?
Kurze Antwort:
Ein untergeordneter Bereich erbt normalerweise prototypisch von seinem übergeordneten Bereich, jedoch nicht immer. Eine Ausnahme von dieser Regel ist eine Direktive mit dem Geltungsbereich: { ... } – dadurch wird ein „isolierter“ Geltungsbereich erstellt, der nicht prototypisch erbt. Dieses Konstrukt wird häufig beim Erstellen einer Direktive für „wiederverwendbare Komponenten“ verwendet.
Was die Nuancen betrifft, ist die Bereichsvererbung im Allgemeinen unkompliziert ... bis Sie eine 2-Wege-Datenbindung benötigen (z. B. form Elemente, ng-Modell) im untergeordneten Bereich. Ng-repeat, ng-switch und ng-include können zu Problemen führen, wenn Sie versuchen, vom untergeordneten Bereich aus eine Bindung an ein Primitiv (z. B. eine Zahl, eine Zeichenfolge, ein boolescher Wert) im übergeordneten Bereich herzustellen. Es funktioniert nicht so, wie die meisten Leute es erwarten. Der untergeordnete Bereich erhält seine eigene Eigenschaft, die die gleichnamige übergeordnete Eigenschaft verbirgt/schattet. Ihre Problemumgehungen sind:
Neue AngularJS-Entwickler erkennen oft nicht, dass ng-repeat, ng-switch, ng-view, ng-include und ng-if all neue untergeordnete Bereiche erstellen, also das Problem taucht oft auf, wenn es um diese Anweisungen geht. (Siehe dieses Beispiel für eine schnelle Veranschaulichung des Problems.)
Dieses Problem mit Grundelementen kann leicht vermieden werden, indem man der „Best Practice“ folgt, immer ein „.“ zu haben. in Ihren NG-Modellen – schauen Sie sich 3 Minuten an. Misko demonstriert das Problem der primitiven Bindung mit ng-switch.
Mit einem „.“ in Ihren Modellen stellt sicher, dass die prototypische Vererbung im Spiel ist. Verwenden Sie also:
L-o-n-g Antwort:
Prototypische Vererbung verstehen
Es ist wichtig zu verstehen prototypische Vererbung, bevor wir die Bereichsvererbung besprechen.
Angenommen, parentScope hat die Eigenschaften aString, aNumber, anArray, anObject und aFunction. Wenn childScope prototypisch von parentScope erbt, haben wir:
[Bild des prototypischen Vererbungsdiagramms]
Wenn wir versuchen, vom untergeordneten Bereich aus auf eine im parentScope definierte Eigenschaft zuzugreifen, schaut JavaScript zuerst hinein Suchen Sie im untergeordneten Bereich nicht nach der Eigenschaft, sondern suchen Sie im geerbten Bereich nach der Eigenschaft. (Wenn es die Eigenschaft nicht im parentScope finden würde, würde es in der Prototypenkette weitermachen ... bis zum Root-Bereich). Das ist also alles wahr:
childScope.aString === 'parent string' childScope.anArray[1] === 20 childScope.anObject.property1 === 'parent prop1' childScope.aFunction() === 'parent output'
Angenommen, wir machen dann Folgendes:
childScope.aString === 'parent string' childScope.anArray[1] === 20 childScope.anObject.property1 === 'parent prop1' childScope.aFunction() === 'parent output'
Die Prototypkette wird nicht konsultiert und dem childScope wird eine neue aString-Eigenschaft hinzugefügt. Diese neue Eigenschaft verbirgt/schattet die gleichnamige parentScope-Eigenschaft. Dies wird sehr wichtig, wenn wir unten ng-repeat und ng-include besprechen.
[Bild des Diagramms zum Ausblenden von Eigenschaften]
Angenommen, wir machen dann Folgendes:
childScope.aString = 'child string'
Die Prototypenkette wird konsultiert, da die Objekte (anArray und anObject) nicht im childScope gefunden werden. Die Objekte werden im parentScope gefunden und die Eigenschaftswerte werden für die Originalobjekte aktualisiert. Dem childScope werden keine neuen Eigenschaften hinzugefügt. Es werden keine neuen Objekte erstellt. (Beachten Sie, dass Arrays und Funktionen in JavaScript auch Objekte sind.)
[Bild des Folgens des Prototypkettendiagramms]
Angenommen, wir machen dann Folgendes:
childScope.anArray[1] = '22' childScope.anObject.property1 = 'child prop1'
Das Die Prototypenkette wird nicht konsultiert und der untergeordnete Bereich erhält zwei neue Objekteigenschaften, die die gleichnamigen parentScope-Objekteigenschaften ausblenden/schattieren.
[Bild weiterer Eigenschaften Diagramm ausblenden]
Angular Scope Inheritance
Die Konkurrenten:
Standardmäßig erstellen Anweisungen keinen neuen Bereich (d. h. Bereich: false).
ng-include
Angenommen, wir haben in unserem Controller:
childScope.anArray = [100, 555] childScope.anObject = { name: 'Mark', country: 'USA' }
Und in unserem HTML:
$scope.myPrimitive = 50; $scope.myObject = {aNumber: 11};
Jedes ng-include generiert einen neuen untergeordneten Bereich, der prototypisch vom übergeordneten Bereich erbt.
[Bild des Diagramms der untergeordneten ng-include-Bereiche]
Wenn Sie (z. B. „77“) in das erste Eingabetextfeld eingeben, erhält der untergeordnete Bereich eine neue myPrimitive-Bereichseigenschaft, die den übergeordneten Bereich verbirgt/schattet gleichnamige Scope-Eigenschaft.
[Bild von ng-include mit einem primitiven Diagramm]
Die Eingabe (z. B. „99“) in das zweite Eingabetextfeld führt nicht zu einem neuen untergeordneten Element Eigentum. Da tpl2.html das Modell an eine Objekteigenschaft bindet, setzt die prototypische Vererbung ein, wenn das ngModel nach dem Objekt myObject sucht – es findet es im übergeordneten Bereich.
[Bild von ng-include mit einem Objektdiagramm]
Wir können die erste Vorlage so umschreiben, dass sie $parent verwendet, wenn wir unser Modell nicht von einem Grundelement in ein ändern möchten Objekt:
<script type="text/ng-template">
Die Eingabe (z. B. „22“) in dieses Eingabetextfeld führt nicht zu einer neuen untergeordneten Eigenschaft. Das Modell ist jetzt an eine Eigenschaft des übergeordneten Bereichs gebunden (da $parent eine untergeordnete Bereichseigenschaft ist, die auf den übergeordneten Bereich verweist).
[Bild von ng-include mit $parent-Diagramm]
ng-switch
Die Vererbung des Ng-Switch-Bereichs funktioniert genauso wie ng-include. Wenn Sie also eine bidirektionale Datenbindung an ein Grundelement im übergeordneten Bereich benötigen, verwenden Sie $parent oder ändern Sie das Modell in ein Objekt und binden Sie es dann an eine Eigenschaft dieses Objekts. Dadurch wird vermieden, dass der untergeordnete Bereich die Eigenschaften des übergeordneten Bereichs ausblendet/überschattet.
ng-repeat
Ng-repeat funktioniert etwas anders. Angenommen, wir haben in unserem Controller:
childScope.aString === 'parent string' childScope.anArray[1] === 20 childScope.anObject.property1 === 'parent prop1' childScope.aFunction() === 'parent output'
Und in unserem HTML:
childScope.aString = 'child string'
Für jedes Element/jede Iteration erstellt ng-repeat einen neuen Bereich, der prototypisch vom übergeordneten Element erbt Der Wert des Elements wird jedoch auch einer neuen Eigenschaft im neuen untergeordneten Bereich zugewiesen (die neue Eigenschaft ist der Name der Schleifenvariablen). Hier ist, was der Angular-Quellcode für ng-repeat tatsächlich ist:
childScope.anArray[1] = '22' childScope.anObject.property1 = 'child prop1'
Wenn das Element ein Grundelement ist (wie in myArrayOfPrimitives), wird im Wesentlichen eine Kopie des Werts der neuen untergeordneten Bereichseigenschaft zugewiesen. Wenn Sie den Wert der Eigenschaft des untergeordneten Bereichs ändern (z. B. mithilfe von ng-model, daher die Nummer des untergeordneten Bereichs), wird das Array, auf das der übergeordnete Bereich verweist, nicht geändert. Im ersten ng-repeat oben erhält also jeder untergeordnete Bereich eine Num-Eigenschaft, die unabhängig vom myArrayOfPrimitives-Array ist:
[Bild von ng-repeat mit Primitives-Diagramm]
Dieses ng-repeat wird nicht funktionieren (wie Sie es wollen/erwarten). Durch Eingabe in die Textfelder werden die Werte in den grauen Feldern geändert, die nur in den untergeordneten Bereichen sichtbar sind. Wir möchten, dass sich die Eingaben auf das Array „myArrayOfPrimitives“ auswirken und nicht auf eine untergeordnete Primitiveigenschaft. Um dies zu erreichen, müssen wir das Modell in ein Array von Objekten ändern.
Wenn es sich bei dem Element also um ein Objekt handelt, wird dem neuen untergeordneten Bereich ein Verweis auf das Originalobjekt (keine Kopie) zugewiesen Eigentum. Wenn Sie den Wert der Eigenschaft des untergeordneten Bereichs ändern (d. h. mithilfe von ng-model, daher obj.num), wird das Objekt geändert, auf das der übergeordnete Bereich verweist. Im zweiten ng-repeat oben haben wir also:
[Bild des ng-repeat mit Objektdiagramm]
(Ich habe eine Linie grau eingefärbt, nur damit klar ist, wo es geht.)
Das funktioniert wie erwartet. Eintippen in
Das obige ist der detaillierte Inhalt vonWie funktioniert prototypische Vererbung mit bidirektionaler Datenbindung in AngularJS-Bereichen?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!