data - angularjs transclude




AngularJS: Direktive isolate scope-scope Variable undefined (3)

Beide Bereiche: true und scope: {} erstellt einen untergeordneten Bereich für die Anweisung. Aber,

scope: true wird prototypisch die Eigenschaften vom übergeordneten Element erben (z. B. der Controller, in dem die Direktive enthalten ist), wobei arcope: {} die Eigenschaften nicht vom übergeordneten Element erbt und daher isoliert heißt

Da oneWay eine isolierte Bereichsanweisung ist und Sie das Hallo nicht weitergeben, ist es im HTML nicht definiert.

Kann mir jemand erklären, warum attrDir Scope Variable sichtbar ist, und oneWay nicht? Ich dachte, dass scope: {} isoliert ist.

angular.module('test', []);

angular.module('test').directive('attrDir', attrDir);

function attrDir(){
    return {

        scope: true,

        link: function(scope){
          scope.hello = 'attrDir';
        }

    };
}

angular.module('test').directive('oneWay', oneWay);

function oneWay(){
    return {

        scope: {
          data: '<?'
        },

        link: function(scope){
          scope.hello = 'oneWay';  
        }

    };
}

hello wird nur in attr-dir gerendert.

<attr-dir>
  <span>{{hello}}</span>
</attr-dir>
<one-way>
  <span>{{hello}}</span>
</one-way>

Hier ist ein Plünderer: https://plnkr.co/edit/2CM4vVrshWuJvaBj2q8T?p=preview

Danke.


Erstens, was Sie beobachten, hat nichts mit < Bindung < zu tun.

Das Problem ist, dass der Ausdruck {{hello}} in beiden Direktiven nicht Teil der Vorlage dieser Direktiven ist. Und für solche Elemente sind die Regeln für Bindungen unterschiedlich.

Angular erstellt automatisch Verknüpfungsfunktionen für {{hello}} Ausdrücke. Die Bereiche, für die diese Verknüpfungsfunktionen ausgewertet werden, sind in Ihren Fällen jedoch unterschiedlich.

Was Sie wahrscheinlich erwartet haben, ist dies:

            rootScope
         /             \
        /               \
attr-dir-new-scope  one-way-isoloate-scope
      /                   \
     /                     \
{{hello}}               {{hello}}

Nach diesem Kommentar in der Quelle :

// Wir übergeben nur den isolate-Bereich, wenn die isolate-Direktive eine Vorlage hat,
// Andernfalls gehören die untergeordneten Elemente nicht zur isolate-Direktive.

Das wahre Bild ist das:

             root scope
         /             \    \
        /               \    \
attr-dir-new-scope       \    one-way-isoloate-scope
      /                   \
     /                     \
{{hello}}               {{hello}}

In Ihrem Beispiel erstellt die erste Anweisung <attr-dir> also keinen isolate-Bereich, sondern einen neuen Bereich. Wenn Sie also angular verbinden, übergibt dieser neue Bereich sowohl an die Verknüpfungsfunktion Ihrer Anweisung:

link: function(scope){
     scope.hello = 'attrDir';
}

und zu der Verknüpfungsfunktion, die für den Ausdruck {{hello}} . Wenn Sie in Ihrer Verknüpfungsfunktion einen Wert hinzufügen, ist dies in der Funktion zum Verknüpfen von Ausdrücken verfügbar.

Aber Ihre zweite Direktive <one-way> erstellt isolate scope und entsprechend dem oben erwähnten Kommentar, wird die Verknüpfungsfunktion der Direktive isoliert wie erwartet, aber die Verknüpfungsfunktion des Ausdrucks erhält einen anderen Bereich (root scope in Ihrem Beispiel) ). Sie fügen also hello Wert auf verschiedenen Bereichen hinzu. Deshalb ist der Wert nicht definiert.


Wenn der Bereich nicht angegeben ist, wird der Bereich freigegeben. Wenn der Bereich als wahr angegeben ist, handelt es sich um einen vererbten Bereich. Wenn der Bereich mit geschweiften Klammern angegeben ist, handelt es sich um einen isolierten Bereich.

Der beste Weg, um die Bereiche zu visualisieren, ist die Verwendung von console.log-Anweisungen in Ihren Link-Funktionen.

link: function(scope) {          
      scope.hello = 'attrDir';
      console.log('scope in attrDir: ', scope);
    }

    link: function(scope) {          
          scope.hello = 'oneWay';
          console.log('scope in oneWay: ', scope);
        }

Wenn Sie die Entwicklerwerkzeuge öffnen, sehen Sie, dass die erste Direktive ihren übergeordneten Bereich in ihrem Prototyp erbt

__proto__:Scope 

während der zweite ein Objekt mit einem eigenen Bereich ist (indem Sie geschweifte Klammern verwendeten, gaben Sie ihm einen Isolationsbereich)

__proto__:Object




angularjs-scope