La Directive isoler portée avec ng-repeat portée en AngularJS

J'ai une directive avec un isolat-portée (de sorte que je peux réutiliser la directive dans d'autres lieux), et quand j'utilise cette directive avec une ng-repeat, cela ne fonctionne pas.

J'ai lu l'ensemble de la documentation et de la Pile Dépassement de réponses sur ce sujet et de comprendre les enjeux. Je crois que j'ai évité tous les pièges.

Donc, je comprends que mon code ne fonctionne pas parce que le champ créé par le ng-repeat directive. Mon propre directive crée un isolat-champ d'application et fait dans les deux sens de la liaison de données à un objet de la portée parent. Mon directive assigne un nouvel objet-valeur de cette variable liée et cela fonctionne parfaitement lors de mon directive est utilisée sans ng-repeat (la variable parent est correctement mis à jour). Cependant, avec ng-repeat, la cession crée une nouvelle variable dans la ng-repeat portée et la variable parent ne voit pas le changement. Tout cela est prévu sur la base de ce que j'ai lu.

J'ai aussi lu que lorsqu'il y a plusieurs directives sur un élément donné, qu'un seul champ est créé. Et qu'un priority peut être définie dans chaque directive pour définir l'ordre dans lequel les directives sont appliquées; les directives sont classées par ordre de priorité, puis leur compiler les fonctions sont appelés (de recherche pour le mot priorité à http://docs.angularjs.org/guide/directive).

Alors j'espérais que je pourrais utiliser en priorité pour faire en sorte que mon directive s'exécute en premier et finit par créer un isolat-champ, et quand ng-repeat s'exécute, il ré-utilise l'isolat-champ d'application au lieu de la création d'un champ qui fait hérite de la portée parent. Le ng-repeat documentation indique que celle-ci s'exécute à un niveau de priorité 1000. Il n'est pas clair si 1 est d'un plus haut niveau de priorité ou une diminution du niveau de priorité. Lorsque j'ai utilisé le niveau de priorité 1 dans mon directive, il n'est pas de faire une différence, alors j'ai essayé 2000. Mais cela ne fait qu'aggraver les choses: mon liaisons bidirectionnelles devenir undefined et mon directive ne pas afficher quoi que ce soit.

J'ai créé un violon pour montrer mon problème. J'ai commenté la priority paramètre dans mon directive. J'ai une liste de nom des objets et une directive appelée name-row qui montre les champs prénom et nom dans le nom de l'objet. Quand un nom affiché est cliqué, je le veux pour définir un selected variable dans le champ d'application principal. Le tableau de noms, la selected variable sont passés à la name-row directive à l'aide de deux voies de liaison de données.

Je sais comment obtenir que cela fonctionne par appel à des fonctions dans le champ d'application principal. Je sais aussi que si selected est à l'intérieur d'un autre objet, et je la lie à l'objet extérieur, les choses allaient tourner. Mais je ne suis pas intéressé par ces solutions à l'heure actuelle.

Au lieu de cela, les questions que j'ai sont:

  • Comment puis-je empêcher ng-repeat de la création d'un champ qui fait hérite de la portée parent, et, au lieu de l'avoir utiliser mon directive isoler le-champ?
  • Pourquoi le niveau de priorité 2000 dans mon directive ne fonctionne pas?
  • À l'aide de Batarang, est-il possible de savoir quel type de champ d'application est en cours d'utilisation?
  • Normalement, vous ne voulez pas utiliser un isolat la portée si votre directive sur le même élément avec d'autres directives. Puisque vous êtes la création de vos propres propriétés de l'étendue, et vous avez besoin de travailler avec ng-repeat, je vous suggère d'utiliser scope: true pour votre directive. Voir aussi (si vous ne l'avez pas déjà) stackoverflow.com/questions/14914213/... Aussi, juste parce que une directive sera utilisé dans plusieurs endroits ne signifie pas que nous devrions utiliser automatiquement un isolat portée.
  • J'ai lu beaucoup de vos réponses (elles sont au-delà excellent, merci pour l'écriture), mais il n'a jamais eu lieu pour moi de lire vos questions :-). J'ai lu ce que vous avez lié. Il me semble que les isoler-champ d'application les directives ne peuvent pas être mélangé avec d'autres directives. Je suis d'accord avec le sentiment que ces directives sont des composants et, par conséquent, ils ne doivent pas être mélangés avec d'autres directives. La seule exception (à ce jour) pour moi, ce serait ng-repeat. Je pense qu'il est utile d'être capable de mélanger autonome des directives ng-repeat. À suivre...
  • Suite de la ci-dessus... Donc si il doit y avoir qu'une directive avec un champ d'application pour un élément, puis ng-repeat ne doit pas avoir une portée. ng-repeat avoir un champ d'application ne font sens pour le type de cas d'utilisation, donc je ne veux pas dire qu'il soit changé. Au lieu de cela, comme je l'ai commenté dans Alex Osborn réponse, je pense que je vais créer une répétition de la directive fondée sur l' ng-repeat ne pas créer son propre champ. Cela peut ensuite être utilisé pour la répétition des directives qui ont leur propre isoler étendues. À suivre...
  • Le code qui se répète d'une directive doit maintenant de savoir si l'utilisation de ng-repeat ou la portée personnalisée-moins de répéter la directive. Je pense que c'est correct pour le "visiteur" pour le connaître, mais il n'est pas acceptable pour un "appelé" (la directive être répétés) pour savoir si elle est répétée, ou pas. À suivre...
  • Un peu fou avec les commentaires ici... 🙂 ngRepeat doit créer son propre champ d'application. Pourquoi avez-vous besoin d'un isolat de portée ici?
  • Aussi, je pense que c'est important pour un composant (directive) pour être en mesure de changer dans le futur, sans casser le code qui l'utilise, surtout si le composant est simplement l'ajout d'un comportement sans changer son "API" (c'est à dire qu'il n'a pas besoin de liaisons supplémentaires pour soutenir le nouveau comportement). Le nouveau comportement pourrait avoir besoin d'un isolat-champ où aucun n'a été nécessaire avant de pouvoir stocker de la composante spécifique de l'état. Je pense donc qu'il n'est pas idéal d'avoir à décider quel type de champ à utiliser pour un composant "directive", basée sur les habitudes d'utilisation de ce composant. </soapbox>
  • désolé pour le firehose de commentaires :-). Ma première fois avec stackoverflow; peut-être que cela aurait été mieux dans la AngularJS Groupe Google. J'ai fait le plus petit possible violon pour montrer que je ne pouvais pas mélanger mon directive ng-repeat. Mon code a la directive spécifique de l'état que je ne veux isoler de la portée parent. Pensez-vous que je vais pouvoir créer mon propre variante de ng-repeat qui utilise une autre directive, ou est-il quelque chose de fondamental dans ng-repeat qui ne peuvent pas fonctionner avec un autre directive? Je suis un JS newb & n'ont pas pris un coup d'oeil au Angulaire code encore.
  • ngRepeat passe par la création d'un ensemble d'éléments DOM, l'ajout d'une portée de chacun, et puis la création de certaines variables sur chaque champ contenant l'itération de la valeur et de certaines métadonnées. Il ne peut pas fonctionner sans une couverture différente. Si vous avez écrit votre propre, il serait enclin à l'erreur - il exiger qu'il y a déjà un champ créé par une priorité plus élevée de la directive, puis votre nouveau répéteur ne pollue champ d'application. Tant pour l'isolation! Cela dit, vous pouvez l'utilisation ngRepeat et un isolat portée, donc je ne suis pas sûr de ce qu'est la question.
  • Ma question: l'Écriture d'un 2-way liaison de données dans un personnalisé directive isoler-champ d'application échoue avec ng-repeat. Votre plunker utilise 2 voies de la liaison de données, mais il ne lit que la variable liée; il n'est pas d'écrire une variable liée. Je n'ai pas besoin d'écrire à la variable pointant vers l'itération en cours (val dans votre plunker), mais j'ai d'autres variables que j'lier à dans mon de la directive isoler-champ d'application et j'ai besoin d'être en mesure de modifier ces variables à partir de l'intérieur de mon directive. Par exemple, dans mon violon (lié à ma question), j'ai besoin de modifier ioSelected, et qui ne fonctionne pas lorsque j'utilise ng-repeat.
  • Oh, eh bien la réponse est encore plus simple. Utilisation io-selected="$parent.selected".
  • Mais aussi garder à l'esprit que votre problème n'est pas avec ngRepeat mais avec la façon dont l'héritage par prototype fonctionne en JavaScript. Le problème est que vous êtes à l'aide d'une primitive. Modèle de valeurs doivent toujours avoir un . en AngularJS.
  • Je pense que vous êtes la création d'une directive, lorsque l'un n'est pas nécessaire. Apparemment, de ce que vous tentez de le faire peut être réalisé par une combinaison de ng-inclure et ng-repeat. Mettre dans un Contrôleur pour chaque élément répété et vous êtes bon pour aller.
  • Je pensais que l'utilisation de $parent est un code-odeur. Que faire si mon directive est imbriquée dans plusieurs ng-repeat directives? Puis mon directive aurait pour savoir à quelle profondeur le terrier du lapin va de la chaîne et tout un tas de $parent.$parent..., droit? ng-repeat introduit une portée parce qu'il a besoin de faire de l'itération en cours à la disposition de chaque répétition. Mais que faire si j'ai une répétition de la variante qui lie l'itération courante à une entrée dans la directive? Ensuite, la répétition de la directive n'a pas besoin d'introduire une portée de tous. Mais j'ai besoin de regarder dans les métadonnées que vous avez dit ng-repeat besoins.
  • mon violon est le plus petit exemple pour illustrer, je ne peut pas écrire dans un 2-way de liaison lorsque j'utilise ng-repeat. J'aime le concept de directives (et 2 voies de la liaison de données) et j'ai une très minime contrôleur autonome dans mon (pleine page) app (j'espère que je vais être capable d'en finir avec ce contrôleur, mais je m'égare). Donc, je suis à la recherche d'un moyen de faire mon directives de travail dans n'importe quel scénario avec 2 voies de la liaison de données.
  • Quelqu'un peut m'aider avec ça? stackoverflow.com/questions/22000201/...

InformationsquelleAutor Deepak Nulu | 2013-03-25