Frage Was ist der Unterschied zwischen "@" und "=" im Richtlinienumfang von AngularJS?


Ich habe die AngularJS-Dokumentation zu diesem Thema sorgfältig gelesen und dann mit einer Direktive getüftelt. Hier ist die Geige.

Und hier sind einige relevante Schnipsel:

  • Aus dem HTML:

    <pane bi-title="title" title="{{title}}">{{text}}</pane>
    
  • Aus der Fenster-Direktive:

    scope: { biTitle: '=', title: '@', bar: '=' },
    

Es gibt einige Dinge, die ich nicht verstehe:

  • Warum muss ich verwenden? "{{title}}" mit '@' und "title" mit '='?
  • Kann ich auch direkt auf den übergeordneten Bereich zugreifen, ohne mein Element mit einem Attribut zu dekorieren?
  • Die Dokumentation sagt "Oft ist es wünschenswert, Daten aus dem isolierten Bereich über einen Ausdruck an den übergeordneten Bereich zu übergeben", aber das scheint auch mit der bidirektionalen Bindung zu funktionieren. Warum sollte der Ausdruck Route besser sein?

Ich habe eine andere Geige gefunden, die auch die Ausdruckslösung zeigt: http://jsfiddle.net/maxisam/QrCXh/


996
2017-12-27 06:10


Ursprung


Antworten:


Warum muss ich "{{title}}" mit '@'und' titel 'mit'='?

@ bindet eine lokale / richtlinien scope-Eigenschaft an die bewerteter Wert des DOM-Attributs. Wenn du benutzt title=title1 oder title="title1"Der Wert des DOM-Attributs "title" ist einfach die Zeichenfolge title1. Wenn du benutzt title="{{title}}"Der Wert des DOM-Attributs "title" ist der interpolierte Wert von {{title}}Daher entspricht die Zeichenfolge der übergeordneten Eigenschaft, auf die die Eigenschaft "title" derzeit festgelegt ist. Da Attributwerte immer Zeichenfolgen sind, erhalten Sie immer einen Zeichenfolgenwert für diese Eigenschaft im Anwendungsbereich der Anweisung, wenn Sie sie verwenden @.

= bindet eine lokale / director -Scope-Eigenschaft an eine übergeordnete Bereichseigenschaft. Also mit =, verwenden Sie den übergeordneten Modell- / Bereichseigenschaftsnamen als Wert des DOM-Attributs. Sie können nicht verwenden {{}}s mit =.

Mit @ können Sie Dinge wie machen title="{{title}} and then some" - {{title}} wird interpoliert, dann wird die Zeichenfolge "and them some" damit verkettet. Die letzte verkettete Zeichenfolge ist das, was die lokale / director-Bereichseigenschaft erhält. (Sie können das nicht mit =, nur @.)

Mit @, müssen Sie verwenden attr.$observe('title', function(value) { ... }) wenn Sie den Wert in Ihrer Link (ing) -Funktion verwenden müssen. Z.B., if(scope.title == "...") wird nicht so funktionieren, wie du es erwartest. Beachten Sie, dass Sie nur auf dieses Attribut zugreifen können asynchron. Sie müssen $ observe () nicht verwenden, wenn Sie nur den Wert in einer Vorlage verwenden. Z.B., template: '<div>{{title}}</div>'.

Mit =, Sie müssen $ observe nicht verwenden.

Kann ich auch direkt auf den übergeordneten Bereich zugreifen, ohne mein Element mit einem Attribut zu dekorieren?

Ja, aber nur, wenn Sie keinen isolierten Bereich verwenden. Entfernen Sie diese Zeile aus Ihrer Anweisung

scope: { ... } 

und dann wird Ihre Anweisung keinen neuen Bereich erstellen. Es wird den übergeordneten Bereich verwenden. Sie können dann direkt auf alle Eigenschaften des übergeordneten Bereichs zugreifen.

Die Dokumentation sagt "Oft ist es wünschenswert, Daten aus dem isolierten Bereich über einen Ausdruck und an den übergeordneten Bereich zu übergeben", aber das scheint auch mit der bidirektionalen Bindung zu funktionieren. Warum sollte der Ausdruck Route besser sein?

Ja, durch die bidirektionale Bindung können der lokale / direktive und der übergeordnete Bereich Daten gemeinsam nutzen. "Ausdrucksbindung" ermöglicht der Anweisung, einen Ausdruck (oder eine Funktion) aufzurufen, der durch ein DOM-Attribut definiert ist - und Sie können auch Daten als Argumente an den Ausdruck oder die Funktion übergeben. Wenn Sie also keine Daten mit dem übergeordneten Element teilen müssen - Sie möchten nur eine Funktion aufrufen, die im übergeordneten Bereich definiert ist - können Sie das verwenden & Syntax.

Siehe auch


1109
2017-12-28 01:15



Es gibt viele gute Antworten hier, aber ich möchte meine Perspektive auf die Unterschiede zwischen anbieten @, =, und & Bindung, die sich für mich als nützlich erwiesen hat.

Alle drei Bindungen bieten Möglichkeiten zum Übergeben von Daten aus dem übergeordneten Bereich an den isolierten Bereich der Richtlinie durch die Attribute des Elements:

  1. @ Bindung ist für das Passieren von Strings.      Diese Zeichenfolgen unterstützen {{}} Ausdrücke für interpolierte Werte.      Beispielsweise:      . Der interpolierte Ausdruck wird gegen ausgewertet      der übergeordnete Bereich der Richtlinie.

  2. = Bindung ist für Zwei-Wege-Modellbindung. Das Modell im übergeordneten Bereich      ist im isolierten Geltungsbereich der Richtlinie an das Modell gebunden. Änderungen an      Ein Modell beeinflusst das andere und umgekehrt.

  3. & Die Bindung dient dazu, eine Methode in den Anwendungsbereich Ihrer Richtlinie zu übernehmen      Es kann innerhalb Ihrer Direktive aufgerufen werden. Die Methode ist vorab gebunden      der übergeordnete Bereich der Richtlinie und unterstützt Argumente. Wenn die Methode beispielsweise hallo (name) im übergeordneten Bereich ist, dann in      Um die Methode innerhalb Ihrer Anweisung auszuführen, müssen Sie      rufe $ scope.hello ({name: 'world'})

Ich finde, dass es einfacher ist, sich an diese Unterschiede zu erinnern, indem man sich auf die Scope-Bindings durch eine kürzere Beschreibung bezieht:

  • @  Attributstring-Bindung
  • =  Zwei-Wege-Modell verbindlich
  • &  Callback-Methodenbindung

Die Symbole verdeutlichen auch, was die Gültigkeitsbereichsvariable innerhalb der Implementierung Ihrer Anweisung darstellt:

  • @  Zeichenfolge
  • =  Modell-
  • &  Methode

In der Reihenfolge der Nützlichkeit (für mich sowieso):

  1. =
  2. @
  3. &

524
2018-02-03 23:30



Das = bedeutet bidirektionale Bindung, also eine Referenz auf eine Variable zum übergeordneten Bereich. Das bedeutet, wenn Sie die Variable in der Direktive ändern, wird sie auch im übergeordneten Bereich geändert.

@ bedeutet, dass die Variable in die Direktive kopiert (geklont) wird.

Soweit ich weiss, <pane bi-title="{{title}}" title="{{title}}">{{text}}</pane> sollte auch funktionieren. bi-title wird den Wert des übergeordneten Bereichs erhalten, der in der Direktive geändert werden kann.

Wenn Sie mehrere Variablen im übergeordneten Bereich ändern müssen, können Sie eine Funktion für den übergeordneten Bereich innerhalb der Direktive ausführen (oder Daten über einen Service übergeben).


60
2017-12-27 06:20



Wenn Sie mehr darüber erfahren möchten, wie dies mit einem Live-Beispiel funktioniert. http://jsfiddle.net/juanmendez/k6chmnch/

var app = angular.module('app', []);
app.controller("myController", function ($scope) {
    $scope.title = "binding";
});
app.directive("jmFind", function () {
    return {
        replace: true,
        restrict: 'C',
        transclude: true,
        scope: {
            title1: "=",
            title2: "@"
        },
        template: "<div><p>{{title1}} {{title2}}</p></div>"
    };
});

36
2017-11-21 23:19



@  Als String erhalten

  • Dies erzeugt keinerlei Bindungen. Sie erhalten einfach das Wort, das Sie als String übergeben haben

=  2-Wege-Bindung

  • Änderungen, die vom für die Verarbeitung Verantwortlichen vorgenommen werden, spiegeln sich in dem Verweis der Richtlinie wider und umgekehrt

&Dies verhält sich ein bisschen anders, weil der Bereich eine Funktion bekommt, die gibt das Objekt zurück, das übergeben wurde. Ich gehe davon aus, dass dies notwendig war, damit es funktioniert. Die Geige sollte das klarstellen.

  • Nach dem Aufruf dieser Getter-Funktion verhält sich das resultierende Objekt wie folgt:
    • wenn ein Funktion wurde übergeben: dann wird die Funktion beim Aufruf in der übergeordneten (Controller-) Schließung ausgeführt
    • wenn ein nicht funktionierend wurde übergeben: Holen Sie sich einfach eine lokale Kopie des Objekts, das keine Bindungen hat


Diese Geige sollte zeigen, wie sie funktioniert. Achten Sie besonders auf die Funktionen des Oszilloskops mit get... im Namen hoffentlich besser zu verstehen, was ich meine &


36
2017-08-26 03:40



Es gibt drei Möglichkeiten, wie der Anwendungsbereich der Richtlinie erweitert werden kann:

  1. Parent-Bereich: Dies ist die Standardbereichsvererbung.

Die Richtlinie und ihr übergeordneter Bereich (Controller / Direktive, in dem sie liegt) sind gleich. Änderungen an den Bereichsvariablen in der Direktive werden also auch im übergeordneten Controller übernommen. Sie müssen dies nicht als Standard angeben.

  1. Kind Umfang: Direktive erstellt einen untergeordneten Bereich, der vom übergeordneten Bereich erbt, wenn Sie die Bereichsvariable der Anweisung als wahr angeben.

Wenn Sie die Bereichsvariablen innerhalb der Direktive ändern, spiegelt sich dies nicht im übergeordneten Bereich wider, sondern wenn Sie die Eigenschaft einer Bereichsvariablen ändern, die sich im übergeordneten Bereich widerspiegelt, da Sie die Bereichsvariable des übergeordneten Elements tatsächlich geändert haben .

Beispiel,

app.directive("myDirective", function(){

    return {
        restrict: "EA",
        scope: true,
        link: function(element, scope, attrs){
            scope.somvar = "new value"; //doesnot reflect in the parent scope
            scope.someObj.someProp = "new value"; //reflects as someObj is of parent, we modified that but did not override.
        }
    };
});
  1. Isolierter Bereich: Dies wird verwendet, wenn Sie den Bereich erstellen möchten, der nicht vom Controller-Bereich erbt.

Dies passiert, wenn Sie Plugins erstellen, da dies die Richtlinie generisch macht, da sie in jedem HTML-Code platziert werden kann und nicht vom übergeordneten Bereich beeinflusst wird.

Wenn Sie keine Interaktion mit dem übergeordneten Bereich wünschen, können Sie den Bereich einfach als leeres Objekt angeben. mögen,

scope: {} //this does not interact with the parent scope in any way

Meistens ist dies nicht der Fall, da wir eine Interaktion mit dem übergeordneten Bereich benötigen, also möchten wir, dass einige der Werte / Änderungen durchlaufen werden. Aus diesem Grund verwenden wir:

1. "@"   (  Text binding / one-way binding )
2. "="   ( Direct model binding / two-way binding )
3. "&"   ( Behaviour binding / Method binding  )

@ bedeutet, dass die Änderungen aus dem Bereich des Controllers sich im Geltungsbereich der Richtlinie widerspiegeln. Wenn Sie jedoch den Wert im Bereich "Direktive" ändern, wird die Controller-Bereichsvariable nicht beeinflusst.

@ erwartet immer, dass das zugeordnete Attribut ein Ausdruck ist. Dies ist sehr wichtig; Da das Präfix "@" funktioniert, müssen wir den Attributwert in {{}} umbrechen.

= ist bidirektional. Wenn Sie also die Variable im Direktivenbereich ändern, wird auch die Controller-Bereichsvariable beeinflusst

& wird verwendet, um die Controller-Scope-Methode zu binden, so dass wir sie bei Bedarf aus der Direktive aufrufen können

Der Vorteil hierbei ist, dass der Name der Variablen im Controller-Umfang und im Anweisungsbereich nicht identisch sein muss.

Beispiel: Der Direktivenbereich hat eine Variable "dirVar", die mit der Variablen "contVar" des Controllerbereichs synchronisiert. Dies verleiht der Direktive eine Menge Macht und Verallgemeinerung, da ein Controller mit der Variable v1 synchronisieren kann, während ein anderer Controller, der die selbe Direktive verwendet, dirVar mit der Variable v2 synchronisieren kann.

Unten ist das Beispiel der Verwendung:

Die Richtlinie und der Verantwortliche sind:

 var app = angular.module("app", []);
 app.controller("MainCtrl", function( $scope ){
    $scope.name = "Harry";
    $scope.color = "#333333";
    $scope.reverseName = function(){
     $scope.name = $scope.name.split("").reverse().join("");
    };
    $scope.randomColor = function(){
        $scope.color = '#'+Math.floor(Math.random()*16777215).toString(16);
    };
});
app.directive("myDirective", function(){
    return {
        restrict: "EA",
        scope: {
            name: "@",
            color: "=",
            reverse: "&"
        },
        link: function(element, scope, attrs){
           //do something like
           $scope.reverse(); 
          //calling the controllers function
        }
    };
});

Und der html (beachten Sie den Unterschied für @ und =):

<div my-directive
  class="directive"
  name="{{name}}"
  reverse="reverseName()"
  color="color" >
</div>

Hier ist ein Verknüpfung zu dem Blog, der es schön beschreibt.


33
2018-04-26 16:34



Einfach können wir verwenden: -

  1. @ : - für String-Werte für die Einweg-Datenbindung. In einer Richtung Datenbindung können Sie nur den Wert des Bereichs an die Direktive übergeben

  2. = : - für Objektwert für Zwei-Wege-Datenbindung. In einer Zwei-Wege-Datenbindung können Sie den Wert des Bereichs sowohl in Direktive als auch in HTML ändern.

  3. & : - für Methoden und Funktionen.

BEARBEITEN

In unserer Komponente Definition für Winkelversion 1.5 Und darüber
Es gibt vier verschiedene Arten von Bindungen:

  1. =  Zwei-Wege-Datenbindung : - Wenn wir den Wert ändern, wird automatisch aktualisiert
  2. <  Einwegbindung : - wenn wir nur einen Parameter von einem übergeordneten Bereich lesen und ihn nicht aktualisieren wollen.

  3. @ das ist für Zeichenfolge-Parameter

  4. & das ist für Rückrufe Falls Ihre Komponente etwas an ihren übergeordneten Bereich ausgeben soll


21
2017-08-29 10:44