Quelle est la différence entre & vs @ et = dans angularJS

238

Je suis très nouveau sur AngularJS. quelqu'un peut-il m'expliquer la différence entre ces opérateurs AngularJS: &, @ and =lors de l'isolement de la portée avec un exemple approprié.

Nur Rony
la source
1
Voir aussi stackoverflow.com/questions/14050195/…
Mark Rajcok

Réponses:

375

@permet de passer une valeur définie sur l'attribut directive à la portée isolate de la directive. La valeur peut être une simple chaîne ( myattr="hello") ou une chaîne interpolée AngularJS avec des expressions incorporées ( myattr="my_{{helloText}}"). Considérez-le comme une communication "à sens unique" du champ d'application parent à la directive enfant. John Lindquist a une série de courts screencasts expliquant chacun d'eux. La capture d'écran sur @ est ici: https://egghead.io/lessons/angularjs-isolate-scope-attribute-binding

&permet à la portée isolée de la directive de transmettre des valeurs dans la portée parent pour évaluation dans l'expression définie dans l'attribut. Notez que l'attribut directive est implicitement une expression et n'utilise pas la syntaxe d'expression à double accolade. Celui-ci est plus difficile à expliquer dans le texte. Screencast sur & est ici: https://egghead.io/lessons/angularjs-isolate-scope-expression-binding

=définit une expression de liaison bidirectionnelle entre la portée isolée de la directive et la portée parent. Les modifications de la portée enfant sont propagées au parent et vice-versa. Considérez = comme une combinaison de @ et &. Screencast sur = est ici: https://egghead.io/lessons/angularjs-isolate-scope-two-way-binding

Et enfin, voici un screencast qui montre les trois utilisés ensemble dans une seule vue: https://egghead.io/lessons/angularjs-isolate-scope-review

cliff.meyers
la source
1
Merci pour la légende, j'ai mis à jour ma réponse avec les URL correctes.
cliff.meyers
43
Il est un peu dommage que la réponse la mieux notée renvoie à des vidéos derrière un mur de paiement alors qu'il y a probablement beaucoup de contenu gratuit qui contient les mêmes informations.
BenCr
Il y a beaucoup de vidéos qui sont fournies gratuitement par egghead :)
Vatsal
7
moins un pour le contenu payant.
Arel Sapir
109

Je voudrais expliquer les concepts du point de vue de l'héritage de prototypes JavaScript. Si tout va bien aider à comprendre.

Il existe trois options pour définir le champ d'application d'une directive:

  1. scope: false: Défaut angulaire. La portée de la directive est exactement celle de sa portée parent ( parentScope).
  2. scope: true: Angular crée un champ d'application pour cette directive. La portée hérite de manière prototypique parentScope.
  3. scope: {...}: la portée isolée est expliquée ci-dessous.

La spécification scope: {...}définit un isolatedScope. An isolatedScopen'hérite pas des propriétés de parentScope, cependant isolatedScope.$parent === parentScope. Elle se définit par:

app.directive("myDirective", function() {
    return {
        scope: {
            ... // defining scope means that 'no inheritance from parent'.
        },
    }
})

isolatedScopen'a pas d'accès direct à parentScope. Mais parfois, la directive doit communiquer avec le parentScope. Ils communiquent à travers @, =et &. Le sujet sur l' utilisation de symboles @, =et &parlent de scénarios à l' aideisolatedScope .

Il est généralement utilisé pour certains composants communs partagés par différentes pages, comme Modals. Une portée isolée empêche de polluer la portée globale et est facile à partager entre les pages.

Voici une directive de base: http://jsfiddle.net/7t984sf9/5/ . Une image à illustrer est:

entrez la description de l'image ici

@: liaison unidirectionnelle

@passe simplement la propriété de parentScopeà isolatedScope. Il est appelé one-way binding, ce qui signifie que vous ne pouvez pas modifier la valeur des parentScopepropriétés. Si vous connaissez l'héritage JavaScript, vous pouvez facilement comprendre ces deux scénarios:

  • Si la propriété de liaison est de type primitif, comme interpolatedPropdans l'exemple: vous pouvez modifier interpolatedProp, mais parentProp1ne serait pas modifié. Cependant, si vous changez la valeur de parentProp1, interpolatedPropsera écrasé par la nouvelle valeur (quand angulaire $ digest).

  • Si la propriété de liaison est un objet, comme parentObj: puisque celui passé à isolatedScopeest une référence, la modification de la valeur déclenchera cette erreur:

    TypeError: Cannot assign to read only property 'x' of {"x":1,"y":2}

=: liaison bidirectionnelle

=est appelé two-way binding, ce qui signifie que toute modification dans childScopemettra également à jour la valeur dans parentScope, et vice versa. Cette règle fonctionne pour les primitives et les objets. Si vous modifiez le type de liaison de parentObjbe =, vous constaterez que vous pouvez modifier la valeur de parentObj.x. Un exemple typique est ngModel.

&: liaison de fonction

&permet à la directive d'appeler une parentScopefonction et de transmettre une valeur à partir de la directive. Par exemple, vérifiez JSFiddle: & dans la portée de la directive .

Définissez un modèle cliquable dans la directive comme:

<div ng-click="vm.onCheck({valueFromDirective: vm.value + ' is from the directive'})">

Et utilisez la directive comme:

<div my-checkbox value="vm.myValue" on-check="vm.myFunction(valueFromDirective)"></div>

La variable valueFromDirectiveest transmise de la directive au contrôleur parent via {valueFromDirective: ....

Référence: Comprendre les étendues

Joie
la source
Par défaut, les directives utilisent une portée partagée. Si la directive a 'scope: true', alors elle utilise la portée héritée, dans laquelle l'enfant peut voir les propriétés parent mais le parent ne peut pas voir les propriétés internes de l'enfant.
YuMei
1
AngularJS - Scopes isolés - @ vs = vs & ---------- De courts exemples avec explication sont disponibles sur le lien ci-dessous: codeforeach.com/angularjs/angularjs-isolated-scopes-vs-vs
Prashanth
24

Pas mon violon, mais http://jsfiddle.net/maxisam/QrCXh/ montre la différence. La pièce maîtresse est:

           scope:{
            /* NOTE: Normally I would set my attributes and bindings
            to be the same name but I wanted to delineate between 
            parent and isolated scope. */                
            isolatedAttributeFoo:'@attributeFoo',
            isolatedBindingFoo:'=bindingFoo',
            isolatedExpressionFoo:'&'
        }        
jgm
la source
17

@ : liaison unidirectionnelle

= : liaison bidirectionnelle

& : liaison de fonction

Timothy.Li
la source
5
une mise en garde importante à @ n'est pas seulement unidirectionnelle, mais une chaîne en cours
Shawson
@Shawson: Alors, comment lier des non-chaînes à sens unique (par exemple int ou bool)?
OR Mapper
Si votre cœur y est, vous pouvez prendre la valeur de @ et lancer est un int / bool? Sinon, j'utiliserais simplement = ou <
Shawson
7

AngularJS - Scopes isolés - @ vs = vs &


De courts exemples avec explication sont disponibles au lien ci-dessous:

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

@ - liaison unidirectionnelle

Dans la directive:

scope : { nameValue : "@name" }

En vue:

<my-widget name="{{nameFromParentScope}}"></my-widget>

= - reliure bidirectionnelle

Dans la directive:

scope : { nameValue : "=name" },
link : function(scope) {
  scope.name = "Changing the value here will get reflected in parent scope value";
}

En vue:

<my-widget name="{{nameFromParentScope}}"></my-widget>

& - Appel de fonction

Dans la directive:

scope : { nameChange : "&" }
link : function(scope) {
  scope.nameChange({newName:"NameFromIsolaltedScope"});
}

En vue:

<my-widget nameChange="onNameChange(newName)"></my-widget>
Prashanth
la source
5

Il m'a fallu beaucoup de temps pour vraiment comprendre cela. La clé pour moi était de comprendre que "@" est pour les choses que vous voulez évaluer in situ et passées dans la directive comme une constante où "=" passe réellement l'objet lui-même.

Il y a un joli billet de blog qui explique cela à: http://blog.ramses.io/technical/AngularJS-the-difference-between-@-&-and-=-when-declaring-directives-using-isolate-scopes

Peter Nixey
la source