Réponses:
@
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
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:
scope: false
: Défaut angulaire. La portée de la directive est exactement celle de sa portée parent ( parentScope
).scope: true
: Angular crée un champ d'application pour cette directive. La portée hérite de manière prototypique parentScope
.scope: {...}
: la portée isolée est expliquée ci-dessous. La spécification scope: {...}
définit un isolatedScope
. An isolatedScope
n'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'.
},
}
})
isolatedScope
n'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:
@
: 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 parentScope
proprié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 interpolatedProp
dans l'exemple: vous pouvez modifier interpolatedProp
, mais parentProp1
ne serait pas modifié. Cependant, si vous changez la valeur de parentProp1
, interpolatedProp
sera écrasé par la nouvelle valeur (quand angulaire $ digest).
Si la propriété de liaison est un objet, comme parentObj
: puisque celui passé à isolatedScope
est 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 childScope
mettra é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 parentObj
be =
, 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 parentScope
fonction 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 valueFromDirective
est transmise de la directive au contrôleur parent via {valueFromDirective: ...
.
Référence: Comprendre les étendues
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:'&'
}
@ : liaison unidirectionnelle
= : liaison bidirectionnelle
& : liaison de fonction
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>
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