update - angularjs set html title




Was ist der Unterschied zwischen "@" und "=" im Richtlinienumfang von AngularJS? (10)

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

@ bindet eine lokale / directive-Bereichseigenschaft an den evaluierten Wert des DOM-Attributs . Wenn Sie title=title1 oder title="title1" , ist der Wert des DOM-Attributs "title" einfach der String title1 . Wenn Sie title="{{title}}" , ist der Wert des DOM-Attributs "title" der interpolierte Wert von {{title}} , daher wird der String immer der übergeordneten Eigenschaft "title" zugewiesen. Da Attributwerte immer Zeichenfolgen sind, erhalten Sie immer einen Zeichenfolgenwert für diese Eigenschaft im Bereich der Direktive, wenn Sie @ verwenden .

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

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

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

Mit = müssen Sie $ 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 durch ein DOM-Attribut definierten Ausdruck (oder eine Funktion) aufzurufen - 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 die Syntax & verwenden .

Siehe auch

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

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 "{{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 und 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/


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

Wenn Sie {{title}} verwenden, wird nur der übergeordnete Bereichswert an die Ansicht übergeben und ausgewertet. Dies ist auf eine Art beschränkt, was bedeutet, dass sich die Änderung nicht im übergeordneten Bereich widerspiegelt. Sie können '=' verwenden, wenn Sie auch die Änderungen widerspiegeln möchten, die in der untergeordneten Anweisung zum übergeordneten Bereich vorgenommen wurden. Das ist zwei Wege.

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

Wenn in der Direktive das Attribut scope (scope: {}) enthalten ist, können Sie nicht mehr direkt auf den übergeordneten Bereich zugreifen. Aber es ist immer noch möglich, über scope. $ Parent usw. darauf zuzugreifen. Wenn Sie den Bereich von der Direktive entfernen, kann direkt darauf zugegriffen werden.

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?

Es hängt vom Kontext ab. Wenn Sie einen Ausdruck oder eine Funktion mit Daten aufrufen möchten, verwenden Sie &, und wenn Sie Daten teilen möchten, können Sie bidirektional mit '=' arbeiten.

Sie können die Unterschiede zwischen mehreren Möglichkeiten der Übergabe von Daten an die Direktive unter dem folgenden Link finden:

AngularJS - Isolierte Bereiche - @ vs = vs &

http://www.codeforeach.com/angularjs/angularjs-isolated-scopes-vs-vs


Auch wenn der Bereich lokal ist, wie in Ihrem Beispiel, können Sie über die Eigenschaft $parent auf den übergeordneten Bereich zugreifen. Im unten stehenden Code wird angenommen, dass dieser title im übergeordneten Bereich definiert ist. Sie können dann auf den Titel als $parent.title :

link : function(scope) { console.log(scope.$parent.title) },
template : "the parent has the title {{$parent.title}}"

In den meisten Fällen wird der gleiche Effekt jedoch besser mit Attributen erzielt.

Ein Beispiel dafür, wo ich die Notation "&" gefunden habe, die verwendet wird, "um Daten aus dem isolierten Bereich über einen Ausdruck und zum übergeordneten Bereich zu übergeben", war nützlich (und eine wechselseitige Datenbindung konnte nicht verwendet werden) zum Rendern einer speziellen Datenstruktur innerhalb einer ng-Wiederholung.

<render data = "record" deleteFunction = "dataList.splice($index,1)" ng-repeat = "record in dataList" > </render>

Ein Teil des Renderings war eine Lösch-Schaltfläche und hier war es sinnvoll, eine Löschfunktion aus dem externen Bereich über & anzuhängen. In der Render-Anweisung sieht es so aus

scope : { data = "=", deleteFunction = "&"},
template : "... <button ng-click = "deleteFunction()"></button>"

2-Wege-Datenbindung, dh data = "=" kann nicht verwendet werden, da die Löschfunktion bei jedem $digest Zyklus ausgeführt würde, was nicht gut ist, da der Datensatz dann sofort gelöscht und niemals gerendert wird.


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 weiß, <pane bi-title="{{title}}" title="{{title}}">{{text}}</pane> sollte auch funktionieren. bi-title erhält den Wert des übergeordneten Bereichs, 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 Anweisung ausführen (oder Daten über einen Service übergeben).


Einfach können wir verwenden: -

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

  2. = : - für den Objektwert für die 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 Komponentendefinition für Angular Version 1.5 und höher
Es gibt vier verschiedene Arten von Bindungen:

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

  3. @ Dies ist für String-Parameter

  4. & dies ist für Callbacks, falls Ihre Komponente etwas an ihren übergeordneten Bereich ausgeben muss


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

  1. Parent scope : 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. Child scope : directive 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, wird dies nicht im übergeordneten Bereich angezeigt. Wenn Sie jedoch die Eigenschaft einer Bereichsvariablen ändern, spiegelt sich dies im übergeordneten Bereich wider, 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. Daher 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 der Richtlinie ä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 link zum Blog, der es schön beschreibt.


Ich habe alle möglichen Optionen in einer Geige umgesetzt.

Es befasst sich mit allen Optionen:

scope:{
    name:'&'
},

scope:{
    name:'='
},

scope:{
    name:'@'
},

scope:{

},

scope:true,

https://jsfiddle.net/rishulmatta/v7xf2ujm


Ich habe eine kleine HTML-Datei erstellt, die einen Winkelcode enthält, der die Unterschiede zwischen ihnen zeigt:

https://gist.github.com/RobertAKARobin/a02426c375596f0bef89

<!DOCTYPE html>
<html>
  <head>
    <title>Angular</title>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
  </head>
  <body ng-app="myApp">
    <div ng-controller="myCtrl as VM">
      <a my-dir
        attr1="VM.sayHi('Juan')"
        attr2="VM.sayHi('Juan')"
        attr3="VM.sayHi('Juan')"></a>
    </div>
    <script>
    angular.module("myApp", [])
    .controller("myCtrl", [function(){
      var vm = this;
      vm.sayHi = function(name){
        return ("Hey there, " + name);
      }
    }])
    .directive("myDir", [function(){
      var directive = {
        scope: { attr1: "=", attr2: "@", attr3: "&" },
        link: function(scope){
          console.log(scope.attr1);   // logs "Hey there, Juan"
          console.log(scope.attr2);   // logs "VM.sayHi('Juan')"
          console.log(scope.attr3);   // logs "function (a){return h(c,a)}"
          console.log(scope.attr3()); // logs "Hey there, Juan"
        }
      }
      return directive;
    }]);
    </script>
  </body>
</html>

@ 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 der Referenz der Richtlinie wider und umgekehrt

& Dies verhält sich etwas anders, weil der Bereich eine Funktion erhält, die das übergebene Objekt zurückgibt . 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 eine Funktion übergeben wurde, wird die Funktion beim Aufruf im übergeordneten (Controller-) Abschluss ausgeführt
    • Wenn eine Nichtfunktion übergeben wurde, rufen Sie einfach eine lokale Kopie des Objekts ab, das keine Bindungen hat


Diese Geige sollte zeigen, wie sie funktioniert . Achte besonders auf die Scope-Funktionen mit get... im Namen, um hoffentlich besser zu verstehen, was ich über & bedeute


@ und = siehe andere Antworten.

Ein Gotcha über &
TL; DR;
& erhält einen Ausdruck (funktioniert nicht wie in Beispielen in anderen Antworten) von einem Elternteil und setzt ihn als Funktion in der Direktive, die den Ausdruck aufruft. Und diese Funktion hat die Fähigkeit, jede Variable (gerade Funktionsbezeichnung) des Ausdrucks zu ersetzen , indem ein Objekt mit den Variablen übergeben wird.

erklärt
& ist eine Ausdrucksreferenz, <myDirective expr="x==y"></myDirective> wenn Sie etwas wie <myDirective expr="x==y"></myDirective>
In der Direktive wird dieser expr eine Funktion sein, die den Ausdruck wie expr aufruft:
function expr(){return x == y} .
also in der html-Anweisung <button ng-click="expr()"></button> wird der Ausdruck aufgerufen. In js der Direktive wird nur $scope.expr() den Ausdruck auch aufrufen.
Der Ausdruck wird mit $ scope.x und $ scope.y des übergeordneten Elements aufgerufen.
Sie haben die Möglichkeit, die Parameter zu überschreiben!
Wenn Sie sie nach Aufruf festlegen, z. B. <button ng-click="expr({x:5})"></button>
dann wird der Ausdruck mit Ihrem Parameter x und dem Parent-Parameter y aufgerufen.
Sie können beide überschreiben.
Jetzt wissen Sie, warum <button ng-click="functionFromParent({x:5})"></button> funktioniert.
Weil es nur den Ausdruck des übergeordneten <myDirective functionFromParent="function1(x)"></myDirective> aufruft (zB <myDirective functionFromParent="function1(x)"></myDirective> ) und mögliche Werte durch die angegebenen Parameter ersetzt, in diesem Fall x .
es könnte sein:
<myDirective functionFromParent="function1(x) + 5"></myDirective>
oder
<myDirective functionFromParent="function1(x) + z"></myDirective>
mit Kinderanruf:
<button ng-click="functionFromParent({x:5, z: 4})"></button>
oder sogar mit Funktionsersatz:
<button ng-click="functionFromParent({function1: myfn, x:5, z: 4})"></button> .

es ist nur ein Ausdruck, egal ob es eine Funktion oder viele Funktionen oder nur ein Vergleich ist. Und Sie können jede Variable dieses Ausdrucks ersetzen.

Beispiele:
Richtlinie Vorlage vs aufgerufenen Code:
Parent hat $ scope.x, $ scope.y definiert:
<myDirective expr="x==y"></myDirective> Vorlage: <myDirective expr="x==y"></myDirective>
<button ng-click="expr()"></button> ruft $scope.x==$scope.y
<button ng-click="expr({x: 5})"></button> ruft 5 == $scope.y
<button ng-click="expr({x:5, y:6})"></button> ruft 5 == 6

Parent hat $ scope.function1, $ scope.x, $ scope.y definiert:
<myDirective expr="function1(x) + y"></myDirective> Vorlage: <myDirective expr="function1(x) + y"></myDirective>

<button ng-click="expr()"></button> ruft $scope.function1($scope.x) + $scope.y
<button ng-click="expr({x: 5})"></button> ruft $scope.function1(5) + $scope.y
<button ng-click="expr({x:5, y:6})"></button> ruft $scope.function1(5) + 6
Direktive hat $ scope.myFn als Funktion:
<button ng-click="expr({function1: myFn, x:5, y:6})"></button> ruft $scope.myFn(5) + 6





isolated-scope