1109 votes

Quelle est la différence entre '@' et '=' dans la portée de la directive

J'ai lu le AngularJS la documentation sur le sujet attentivement, puis bricolé autour d'une directive. Voici le violon.

Et voici quelques extraits:

  • à partir du html:

    <pane bi-title="title" title="{{title}}">{{text}}</pane>
    
  • à partir du volet de la directive:

    scope: { biTitle: '=', title: '@', bar: '=' },
    

Il y a plusieurs choses que je ne comprends pas:

  • pourquoi dois-je utiliser "{{titre}}" par " @ " et "titre" par"="?
  • je peux également accéder à la portée parent directement, sans la décoration de mon élément avec un attribut?
  • La documentation dit "il est Souvent souhaitable de transmettre des données à partir de l'isolé portée par une expression et de la portée parent", mais qui semble bien fonctionner avec une liaison bidirectionnelle. Pourquoi l'expression de la route de mieux?

J'ai trouvé un autre violon qui montre l'expression de la solution: http://jsfiddle.net/maxisam/QrCXh/

1169voto

Mark Rajcok Points 85912

pourquoi dois-je utiliser "{{titre}}" par " @ " et "titre" par"="?

@ lie un local/directive champ d'application de la propriété à la valeur évaluée de la DOM attribut. Si vous utilisez title=title1 ou title="title1", la valeur de DOM attribut "title" est tout simplement la chaîne de caractères title1. Si vous utilisez title="{{title}}", la valeur de la DOM attribut "title" est la valeur interpolée de {{title}}, d'où la chaîne de caractères sera quelle que soit la portée parent propriété "title" est actuellement défini. Puisque les valeurs d'attribut sont toujours des chaînes, vous vous retrouvez toujours avec une chaîne de valeur pour cette propriété du champ de la directive lors de l'utilisation de @.

= lie un local/directive champ d'application de la propriété d' un parent champ d'application de la propriété. Donc, avec =, vous utilisez le modèle parent/champ d'application nom de la propriété que la valeur de la DOM attribut. Vous ne pouvez pas utiliser {{}}s avec =.

Avec @, vous pouvez faire des choses comme title="{{title}} and then some" -- {{titre}} est interpolée, alors la chaîne de caractères "et quelques" est concaténé avec elle. Le final de la chaîne concaténée est ce que le local/directive champ d'application de la propriété obtient. (Vous ne pouvez pas faire cela avec =, seul @.)

Avec @, vous aurez besoin d'utiliser attr.$observe('title', function(value) { ... }) si vous avez besoin d'utiliser la valeur dans votre lien(ing) de la fonction. E. g., if(scope.title == "...") ne fonctionne pas comme vous vous attendez. Notez que cela signifie que vous ne pouvez accéder à cet attribut de manière asynchrone. Vous n'avez pas besoin d'utiliser $observer() si vous utilisez uniquement la valeur dans un modèle. E. g., template: '<div>{{title}}</div>'.

Avec =, vous n'avez pas besoin d'utiliser $observer.

je peux également accéder à la portée parent directement, sans la décoration de mon élément avec un attribut?

Oui, mais seulement si vous n'utilisez pas un isolat portée. Supprimer cette ligne à partir de votre directive -- scope: { ... } - et puis votre directive ne va pas créer un nouveau champ d'application. Il va utiliser la portée parent. Vous pouvez alors accéder à l'ensemble de la portée parent directement des propriétés.

La documentation dit "il est Souvent souhaitable de transmettre des données à partir de l'isolé portée par une expression et de la portée parent", mais qui semble bien fonctionner avec une liaison bidirectionnelle. Pourquoi l'expression de la route de mieux?

Oui, bidirectionnel liaison permet le local/directive champ d'application et la portée parent de partager des données. "L'Expression" liaison permet à la directive de recourir à une expression (ou la fonction) définie par un DOM attribut -- et vous pouvez également transmettre des données comme des arguments de l'expression ou de la fonction. Donc, si vous n'avez pas besoin de partager des données avec le parent -- vous voulez juste pour appeler une fonction définie dans la portée parent -- vous pouvez utiliser la syntaxe.

Voir aussi

67voto

asgoth Points 14599

Le '=' signifie bi-directionnelle de liaison, donc une référence à une variable de la portée parent. Cela signifie que, lorsque vous modifiez la variable dans la directive, il sera changé dans le parent de la portée de l'.

'@' signifie que la variable sera copié (cloné) dans la directive.

Autant que je sache, ce

<pane bi-title="{{title}}" title="{{title}}">{{text}}</pane>

devrait fonctionner aussi. bi-titre recevrez le parent champ valeur de la variable, qui peut être changé dans la directive.

Si vous avez besoin de modifier plusieurs variables dans la portée parent, vous pouvez exécuter une fonction sur le parent champ d'application de cette directive (ou de transmettre des données par l'intermédiaire d'un service).

3voto

user3750988 Points 19

Même lorsque la portée est locale, comme dans votre exemple, vous pouvez accéder à la portée parent par le biais de la propriété $parent. Supposons dans le code ci-dessous, qui title est défini sur la portée parent. Vous pourrez ensuite accéder à titre $parent.title:

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

Cependant, dans la plupart des cas, le même effet est meilleur obtenus à l'aide d'attributs.

Un exemple de cas où j'ai trouvé le "&" la notation, qui est utilisée pour transmettre des données à partir de l'isolé portée par une expression et de la portée parent", utile (et dans les deux sens de la liaison de données ne peut pas être utilisé) a été dans une directive pour le rendu spécial discbased à l'intérieur d'une ng-repeat.

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

Une partie du compte-rendu d'une suppression bas et ici, il est utile de joindre un deletefunction de l'extérieur de la portée par et. À l'intérieur de l'rendu de la directive, il ressemble

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

2-voie de liaison de données c'est à dire data = "=" ne peut pas être utilisé tant que la fonction de suppression irait sur chaque $digest cycle, ce qui n'est pas bon, que l'enregistrement est ensuite immédiatement supprimé et jamais rendu.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X