Frage Verwirrt über Angularjs hat Scopes und Bindungen eingeschlossen und isoliert


Ich bemühe mich, den Umfang der Modelle und ihre Verbindun- gen in Bezug auf Richtlinien mit begrenztem Umfang zu verstehen.

Ich verstehe, dass das Beschränken des Gültigkeitsbereichs auf eine Direktive bedeutet, dass controller. $ Scope und directive.scope nicht mehr dasselbe sind. Ich bin jedoch verwirrt darüber, wie sich das Platzieren von Modellen entweder innerhalb der Richtlinienvorlage oder im HTML-Format auf die Datenbindung auswirkt. Ich fühle, dass ich etwas sehr Grundlegendes verpasse und um weiterzugehen, muss ich das verstehen.

Nimm den folgenden Code (Geige hier: http://jsfiddle.net/2ams6/)

JavaScript

var app = angular.module('app',[]);
app.controller('Ctrl',function($scope){
});
app.directive('testel', function(){
    return {
        restrict: 'E',
        scope: {
            title: '@'
        },
        transclude: true,
        template:   '<div ng-transclude>'+
                    '<h3>Template title: {{title}}</h3>' +
                    '<h3>Template data.title:{{data.title}}</h3>' +
                    '</div>'
    }    
}); 

HTML

<div ng-app='app'>
    <div ng-controller="Ctrl">
        <input ng-model="data.title">
        <testel title="{{data.title}}">
            <h3>Transclude title:{{title}}</span></h3>
            <h3>Transclude data.title:{{data.title}}</h3>
        </testel>
    </div>
</div>

Das Modell wird nur aktualisiert {{title}} innerhalb der Vorlage und {{data.title}} in der Einspielung. Warum nicht {{title}} in der Transkription noch nicht {{data.title}} in der Vorlage?

Verschieben Sie die Eingabe so in die Transclusion (Geige hier: http://jsfiddle.net/eV8q8/1/):

<div ng-controller="Ctrl">
    <testel title="{{data.title}}">
        <input ng-model="data.title">
         <h3>Transclude title: <span style="color:red">{{title}}</span></h3>

         <h3>Transclude data.title: <span style="color:red">{{data.title}}</span></h3>

    </testel>
</div>

bedeutet jetzt nur transclude {{data:title}} wird aktualisiert. Warum nicht beide Vorlagen? {{title}} oder {{data.title}}noch übertragen {{title}}?

Und schließlich, die Eingabe in die Vorlage verschieben, so (so geige hier: http://jsfiddle.net/4ngmf/2/):

template: '<div ng-transclude>' +
            '<input ng-model="data.title" />' +
            '<h3>Template title: {{title}}</h3>' +
            '<h3>Template data.title: {{data.title}}</h3>' +
            '</div>'

Jetzt bedeutet das nur Vorlage {{data.title}} wird aktualisiert. Nochmal, warum nicht die anderen 3 Bindungen?

Ich hoffe, da ist etwas Offensichtliches, das mich ins Gesicht starrt und ich vermisse es. Wenn du mich dazu bringst, das zu bekommen, kaufe ich dir ein Bier oder gebe dir ein paar Punkte oder so etwas. Danke vielmals.


55
2018-05-20 15:34


Ursprung


Antworten:


Deine Geigen erstellen drei Bereiche:

  1. ein mit dem Controller verbundener Bereich Ctrl, durch ng-controller
  2. eine Richtlinie hat den Anwendungsbereich aufgrund von transclude: true
  3. ein Direktivenisolat, wegen scope: { ... }

In fiddle1, bevor wir etwas in das Textfeld eingeben, haben wir folgendes:

enter image description here

Bereich 003 ist der Bereich, der dem Controller zugeordnet ist. Da wir das Textfeld noch nicht eingegeben haben, gibt es kein data Eigentum. Im isolierten Bereich 004 sehen wir, dass a title Eigenschaft wurde erstellt, aber sie ist leer. Es ist leer, weil der übergeordnete Bereich kein a hat data.title Eigentum noch.

Nach dem Tippen my title In das Textfeld haben wir jetzt:

enter image description here

Controller-Bereich 003 hat jetzt einen neuen data Objekteigenschaft (weshalb es gelb gefärbt ist), die eine hat title Eigenschaft jetzt auf festgelegt my title. Seit isolieren Bereich Gültigkeitsbereich title ist eine Einweg-Datenbahn zu dem interpolierten Wert von data.titlees bekommt auch den Wert my title (Der Wert ist gelb gefärbt, weil er sich geändert hat).

Der übertragene Bereich erbt prototypisch vom Controller-Bereich, also kann innerhalb des übersetzten HTML der Winkel der Prototypkette folgen und finden $scope.data.title im übergeordneten Bereich (aber $scope.title existiert dort nicht).

Der isolate-Bereich hat nur Zugriff auf seine eigenen Eigenschaften, also nur auf Eigenschaften title.

In fiddle2 haben wir vor der Eingabe das gleiche Bild wie in fiddle1.

Nach dem Tippen my title:

enter image description here

Beachten Sie, wo das neue data.title Eigentum zeigte sich - im übertragenen Umfang. Der Isolate-Bereich sucht noch data.titleauf dem Controller-Bereich, aber es ist nicht dieses Mal, so dass es title Eigenschaftswert bleibt leer.

In fiddle3 haben wir vor dem Tippen das gleiche Bild wie in fiddle1.

Nach dem Tippen my title:

enter image description here

Beachten Sie, wo das neue data.title Eigentum zeigte sich - auf dem Isolat Umfang. Keiner der anderen Bereiche hat Zugriff auf den isolate-Bereich, also die Zeichenfolge my title wird nirgendwo anders erscheinen.


Update für Angular v1.2:

Mit Veränderung eed299a Angular löscht nun den Transcclusionspunkt, bevor es umschaltet, also das Template title: ... und Template data.title: ... Teile werden nicht angezeigt, es sei denn, Sie ändern die Vorlage so, dass ng-transclude ist für sich selbst, wie zum Beispiel:

'<h3>Template title: <span style="color:red">{{title}}</span></h3>' +
'<h3>Template data.title: <span style="color:red">{{data.title}}</span></h3>' +
'<div ng-transclude></div>'

Im folgenden Update für Angular v1.3 wurde diese Vorlagenänderung vorgenommen.


Update für Angular v1.3 +:

Seit Angular v1.3 ist der übersetzte Bereich jetzt ein untergeordnetes Element des isolierenden Bereichs der Direktive und nicht ein untergeordnetes Element des Steuerungsbereichs. Also in fiddle1, bevor wir irgendwas tippen:

enter image description here

Die Bilder in diesem Update sind mit dem Peri $ Umfang Werkzeug, so sind die Bilder ein bisschen anders. Das @ gibt an, dass wir eine isolierende Bereichseigenschaft haben, die das verwendet @ Syntax, und der rosa Hintergrund bedeutet, dass das Werkzeug keinen Vorfahrenverweis für das Mapping finden konnte (was wahr ist, da wir noch nichts in das Textfeld geschrieben haben).

Nach dem Tippen my title In das Textfeld haben wir jetzt:

enter image description here

Isolieren Sie Eigenschaften, die verwenden @ Die Bindung zeigt immer das Ergebnis der interpolierten Zeichenfolge im Isolationsbereich nach dem @ Symbol. Peri $ scope konnte diesen genauen Zeichenfolgenwert auch in einem übergeordneten Bereich finden. Daher wird auch ein Verweis auf diese Eigenschaft angezeigt.

In Geige 2 haben wir vor der Eingabe das gleiche Bild wie in fiddle1.

Nach dem Tippen my title:

enter image description here

Beachten Sie, wo das neue data.title Eigentum zeigte sich - im übertragenen Umfang. Der Isolate-Bereich sucht noch data.titleauf dem Controller-Bereich, aber es ist nicht dieses Mal, so dass es title Eigenschaftswert bleibt leer.

In fiddle3 haben wir vor dem Tippen das gleiche Bild wie in fiddle1.

Nach dem Tippen my title:

enter image description here

Beachten Sie, wo das neue data.title Eigentum zeigte sich - auf dem Isolat Umfang. Auch wenn der übermittelte Bereich über den Zugriff auf den isolieren Bereich verfügt $parent Beziehung wird es dort nicht suchen title oder data.title - Es wird nur im Bereich des Controllers gesucht (d. h. es folgt der prototypischen Vererbung), und im Controller-Bereich sind diese Eigenschaften nicht definiert.


113
2018-05-23 03:28



Nachdem ich alle Antworten durchgelesen habe, einschließlich Marks fantastischen Schaltplänen, verstehe ich den Umfang und die Vererbung meiner Frage. Ich würde mich über Kommentare freuen, wo dieses Diagramm herunterfällt, damit ich angemessen aktualisieren kann. Ich hoffe, es bietet einfach eine andere Sicht auf das, was Mark präsentiert hat:

Scope inheritance


22
2018-05-24 12:52



Gut gefragt, übrigens! Hoffe, meine Antwort ist so eloquent ..

Die Antwort hat damit zu tun, wie die übertragenen Elemente ihren Geltungsbereich erhalten.

Zusammenfassend haben Sie zwei Bereiche:

  1. Der Umfang des Controllers, der $scope.data.title. (Implizit von Ihrem hinzugefügt input Element)
  2. Der Anwendungsbereich der Richtlinie, der $scope.title.

Wenn Sie den Controller ändern $scope.data.title, Richtlinien $scope.title ändert sich auch.

Sie haben auch zwei Abschnitte von HTML, die übertragene und die Vorlage. Was passiert, ist, dass das übersetzte HTML in der ControllerBereich, und die Vorlage HTML ist in der Richtlinien Umfang. Das übersetzte HTML weiß also nichts darüber titleund der Vorlagenbereich weiß nichts darüber data.title

Genau dafür ist Transclusion bestimmt - um untergeordnete Elemente einer Richtlinie zuzulassen, behalten sie ihren übergeordneten BereichIn diesem Fall der Umfang der Steuerung. Designierte Elemente wissen nicht, dass sie in einer Richtlinie enthalten sind, und haben somit keinen Zugang zum Anwendungsbereich der Richtlinie.

Richtlinientexte haben dagegen nur Zugang zum Anwendungsbereich der Richtlinie.

Ich habe Ihren Code ein wenig geändert, um die Namen ein wenig klarer zu machen (gleiche Funktionalität)

http://jsfiddle.net/yWWVs/2/


8
2018-05-20 16:14