web-dev-qa-db-fra.com

AngularJS: Différences entre = & @ dans la portée de la directive?

Créer un isoler le champ à l'intérieur d'une directive nous permet de mapper le champ externe au = portée interne. Nous avons vu six manières différentes de mapper vers attrbutes:

  1. = attr
  2. & attr
  3. @attr
  4. =
  5. Et
  6. @

À quoi servent chacune de ces options de mappage de portée?

105
Shaun Luttin

Cela peut être déroutant, mais j'espère qu'un exemple simple le clarifiera. Commençons par séparer les liaisons de modèles des comportements.

Voici un violon qui devrait aider à relier les choses: http://jsfiddle.net/jeremylikness/3pvte/

Et expliqué ... si votre directive ressemble à ceci:

<my-directive target="foo"/> 

Ensuite, vous avez ces possibilités pour la portée:

{ target : '=' } 

Cela liera scope.target (directive) à $ scope.foo (scope externe). Cela est dû au fait que = est une liaison bidirectionnelle et que, si vous ne spécifiez rien, le nom de la portée interne est automatiquement mis en correspondance avec le nom de l'attribut de la directive. Les modifications apportées à scope.target mettront à jour $ scope.foo.

{ bar : '=target' } 

Cela va lier scope.bar à $ scope.foo. En effet, encore une fois, nous spécifions une liaison bidirectionnelle, mais indiquons à la directive que le contenu de l'attribut "target" doit apparaître dans l'étendue interne sous la forme "bar". Les modifications apportées à scope.bar mettront à jour $ scope.foo.

{ target : '@' } 

Cela définira scope.target sur "foo" car @ signifie "le prendre littéralement". Les modifications apportées à scope.target ne se propagent pas en dehors de votre directive.

{ bar : '@target' } 

Cela définira scope.bar sur "foo" car @ prend sa valeur de l'attribut target. Les modifications apportées à scope.bar ne se propagent pas en dehors de votre directive.

Parlons maintenant des comportements. Supposons que votre portée externe a ceci:

$scope.foo = function(parm1, parm2) { console.log(parm1 + ": " + parm2); } 

Vous pouvez y accéder de plusieurs manières. Si votre code HTML est:

<my-directive target='foo'>

Ensuite

{ target : '=' } 

Vous permettra d'appeler scope.target (1,2) à partir de votre directive.

Même chose,

{ bar : '=target' }

Vous permet d'appeler scope.bar (1,2) à partir de votre directive.

Le moyen le plus courant consiste à établir cela comme un comportement. Techniquement, esperluette évalue une expression dans le contexte du parent. C'est important. Donc j'aurais pu:

<my-directive target="a+b" />

Et si la portée parent a $ scope.a = 1 et $ scope.b = 2, alors dans ma directive:

{ target: '&' } 

Je peux appeler scope.target () et le résultat sera 3. C'est important - la liaison est exposée en tant que fonction de la portée interne mais la directive peut être liée à une expression.

Une façon plus courante de faire ceci est:

<my-directive target="foo(val1,val2)"> 

Ensuite, vous pouvez utiliser:

{ target: '&' }

Et appelez de la directive:

scope.target({val1: 1, val2: 2}); 

Cela prend l'objet que vous avez transmis, mappe les propriétés sur les paramètres de l'expression évaluée, puis appelle le comportement, en l'occurrence l'appel $ scope.foo (1,2);

Vous pouvez aussi faire ceci:

<my-directive target="foo(1, val)"/>

Cela verrouille le premier paramètre sur le littéral 1 et à partir de la directive:

{ bar: '&target' }

Ensuite:

scope.bar(5) 

Qui appellerait $ scope.foo (1,5);

197
Jeremy Likness

Sommaire

  1. @ attr se lie à la valeur évaluée de la chaîne d'un attribut DOM correspondant.
  2. = attr se lie à la propriété scope d'un attribut DOM correspondant .
  3. & attr se lie à la fonction de portée d'un attribut DOM correspondant .
  4. @
  5. =
  6. &

Nous utilisons les valeurs 4, 5 et 6 si le nom de l'attribut DOM cible correspond au nom de propriété de la portée d'isolat. Voici un exemple violon de l'exemple suivant.

Html

<div ng-app='isolate'>
     <h3>Outer Scope</h3>

    <input type="text" ng-model="myModel" />
    <p>msg: {{ msg }}</p>
     <h3>Inner Scope</h3>

    <div id="inner">
        <div my-directive at="{{ myModel }}" equals="myModel" ampersand="msg=msg+'click'"></div>
    </div>
</div>

Javascript

angular.module('isolate', [])
    .directive('myDirective', function () {
    return {
        template:
            '<label>@attr</label><input value="{{ myAt }}" />' +
            '<label>@</label><input value="{{ at }}" />' +
            '<label>=attr</label><input ng-model="myEquals" />' +
            '<label>=</label><input ng-model="equals" />' +
            '<label>&attr</label><input type="button" ng-click="myAmpersand()" value="Btn" />' +
            '<label>&</label><input type="button" ng-click="ampersand()" value="Btn" />',
        scope: {
            myAt: '@at',
            myEquals: '=equals',
            myAmpersand: '&ampersand',
            at: '@',
            equals: '=',
            ampersand: '&'
        }
    };
});
44
Shaun Luttin