À l'aide d'une directive à l'intérieur d'une ng-repeat, et un mystérieux pouvoir de la portée '@'
Si vous préférez voir la question dans le code de travail, commencez ici: http://jsbin.com/ayigub/2/edit
Considérer cette presque l'équivalent de manières d'écrire un simple direcive:
app.directive("drinkShortcut", function() {
return {
scope: { flavor: '@'},
template: '<div>{{flavor}}</div>'
};
});
app.directive("drinkLonghand", function() {
return {
scope: {},
template: '<div>{{flavor}}</div>',
link: function(scope, element, attrs) {
scope.flavor = attrs.flavor;
}
};
});
Lorsqu'il est utilisé par eux-mêmes, les deux directives de travail et se comportent de façon identique:
<!-- This works -->
<div drink-shortcut flavor="blueberry"></div>
<hr/>
<!-- This works -->
<div drink-longhand flavor="strawberry"></div>
<hr/>
Toutefois, lorsqu'il est utilisé à l'intérieur d'une ng-repeat, seul le raccourci version fonctionne:
<!-- Using the shortcut inside a repeat also works -->
<div ng-repeat="flav in ['cherry', 'grape']">
<div drink-shortcut flavor="{{flav}}"></div>
</div>
<hr/>
<!-- HOWEVER: using the longhand inside a repeat DOESN'T WORK -->
<div ng-repeat="flav in ['cherry', 'grape']">
<div drink-longhand flavor="{{flav}}"></div>
</div>
Mes questions sont:
- Pourquoi le longhand version fonctionne pas à l'intérieur d'une ng-repeat?
- Comment pourriez-vous faire la main version de travail à l'intérieur d'une ng-repeat?
Vous devez vous connecter pour publier un commentaire.
Dans
drinkLonghand
, vous utilisez le codeAu cours de la liaison phase interpolée attributs n'ont pas encore été évalué, de sorte que leurs valeurs sont
undefined
. (Ils travaillent à l'extérieur de lang-repeat
parce que dans ces cas, vous n'utilisez pas la chaîne de l'interpolation, que vous soyez simplement de passage dans une chaîne ordinaire, par exemple, "fraise".) Ceci est mentionné dans le Directives du guide du développeur, avec une méthode surAttributes
qui n'est pas présent dans la documentation de l'API appelé$observe
:Donc, pour résoudre ce problème, votre
drinkLonghand
directive devrait ressembler à ceci:Cependant, le problème, c'est qu'il n'utilise pas un isolat portée; ainsi, la ligne
a le potentiel de remplacer un pré-existante de la variable sur le champ nommé
flavor
. En ajoutant un espace isoler portée aussi ne fonctionne pas; c'est parce Angulaire tentatives pour interpoler la chaîne en fonction du champ de la directive, sur laquelle il n'y a pas d'attribut appeléflav
. (Vous pouvez le tester en ajoutantscope.flav = 'test';
au-dessus de l'appel àattrs.$observe
.)Bien sûr, vous pouvez résoudre ce problème avec un isolat de définition de la portée comme
ou par la création d'un non-isoler enfant
ou en ne comptant pas sur un
template
avec{{flavor}}
et au lieu de faire directement de manipulation du DOM commemais cela va à l'encontre de l'objectif de l'exercice (par exemple, il serait plus simple de n'utiliser que le
drinkShortcut
méthode). Donc, pour faire de cette directive de travail, nous allons sortir le$interpoler
service de faire de l'interpolation nous-mêmes de la directive$parent
portée:Bien sûr, cela ne fonctionne que pour la valeur initiale de
scope.$parent.flav
; si la valeur est capable de changer, vous auriez à utiliser$montre
et de réévaluer le résultat de l'interpolation de la fonctionfn
(je ne suis pas positif sur le dessus de ma tête comment vous savez quoi$watch
; vous pourriez avoir à passer dans une fonction).scope: { flavor: '@' }
est un raccourci pratique pour éviter d'avoir à gérer toute cette complexité.[Mise à jour]
Pour répondre à la question dans les commentaires:
Je n'étais pas sûr à ce sujet, donc j'ai cherché dans la source. J'ai trouvé ce qui suit dans
compile.js
:Il semble donc que
attrs.$observe
peut être dit en interne pour utiliser un champ d'application différent de celui en cours à la base de l'attribut d'observation sur (l'avant-dernière ligne, au-dessus de labreak
). Il peut être tentant d'utiliser vous-même, gardez à l'esprit que quoi que ce soit avec le double-dollar$$
préfixe doit être considéré comme privé Angulaire privée de l'API, et sont sujettes à modification sans avertissement (ne pas mentionner que vous obtenez ce pour libre de toute façon lors de l'utilisation de la@
mode).