Cette question a déjà été battue à mort, mais je la partagerai de toute façon au cas où quelqu'un d'autre serait aux prises avec le désordre horrible qu'est la portée d'AngularJS. Cette couverture de volonté =
, <
, @
, &
et ::
. La rédaction complète peut être trouvée ici .
=
établit une liaison bidirectionnelle. La modification de la propriété dans le parent entraînera un changement dans l'enfant, et vice versa.
<
établit une liaison à sens unique, parent à enfant. La modification de la propriété dans le parent entraînera un changement dans l'enfant, mais la modification de la propriété enfant n'affectera pas la propriété parent.
@
affectera à la propriété enfant la valeur de chaîne de l'attribut tag. Si l'attribut contient une expression , la propriété enfant est mise à jour chaque fois que l'expression est évaluée dans une chaîne différente. Par exemple:
<child-component description="The movie title is {{$ctrl.movie.title}}" />
bindings: {
description: '@',
}
Ici, la description
propriété dans la portée enfant sera la valeur actuelle de l'expression "The movie title is {{$ctrl.movie.title}}"
, où movie
est un objet dans la portée parent.
&
est un peu délicat, et en fait il ne semble pas y avoir de raison impérieuse de l'utiliser. Il vous permet d'évaluer une expression dans la portée parent, en remplaçant les paramètres par des variables de la portée enfant. Un exemple ( plunk ):
<child-component
foo = "myVar + $ctrl.parentVar + myOtherVar"
</child-component>
angular.module('heroApp').component('childComponent', {
template: "<div>{{ $ctrl.parentFoo({myVar:5, myOtherVar:'xyz'}) }}</div>",
bindings: {
parentFoo: '&foo'
}
});
Étant donné parentVar=10
, l'expression parentFoo({myVar:5, myOtherVar:'xyz'})
sera évaluée 5 + 10 + 'xyz'
et le composant sera rendu comme suit:
<div>15xyz</div>
Quand voudriez-vous jamais utiliser cette fonctionnalité alambiquée? &
est souvent utilisé par les utilisateurs pour passer à la portée enfant une fonction de rappel dans la portée parent. En réalité, cependant, le même effet peut être obtenu en utilisant «<» pour passer la fonction, qui est plus simple et évite la syntaxe des accolades maladroites maladroites pour passer les paramètres ( {myVar:5, myOtherVar:'xyz'}
). Considérer:
Rappel en utilisant &
:
<child-component parent-foo="$ctrl.foo(bar)"/>
angular.module('heroApp').component('childComponent', {
template: '<button ng-click="$ctrl.parentFoo({bar:'xyz'})">Call foo in parent</button>',
bindings: {
parentFoo: '&'
}
});
Rappel en utilisant <
:
<child-component parent-foo="$ctrl.foo"/>
angular.module('heroApp').component('childComponent', {
template: '<button ng-click="$ctrl.parentFoo('xyz')">Call foo in parent</button>',
bindings: {
parentFoo: '<'
}
});
Notez que les objets (et les tableaux) sont transmis par référence à la portée enfant, et non copiés. Cela signifie que même s'il s'agit d'une liaison unidirectionnelle, vous travaillez avec le même objet dans la portée parent et la portée enfant.
Pour voir les différents préfixes en action, ouvrez ce plunk .
Liaison unique (initialisation) à l'aide de
::
[Documents officiels]
Les versions ultérieures d'AngularJS introduisent l'option d'avoir une liaison unique, où la propriété de portée enfant n'est mise à jour qu'une seule fois. Cela améliore les performances en éliminant la nécessité de surveiller la propriété parent. La syntaxe est différente de celle ci-dessus; pour déclarer une liaison unique, vous ajoutez ::
devant l'expression dans la balise du composant :
<child-component
tagline = "::$ctrl.tagline">
</child-component>
Cela propagera la valeur de tagline
la portée enfant sans établir de liaison unidirectionnelle ou bidirectionnelle. Remarque : si tagline
est initialement undefined
dans la portée parent, angular le surveillera jusqu'à ce qu'il change, puis effectuera une mise à jour unique de la propriété correspondante dans la portée enfant.
Sommaire
Le tableau ci-dessous montre comment les préfixes fonctionnent selon que la propriété est un objet, un tableau, une chaîne, etc.