AngularJS ng-répéter sans élément html

j'utilise actuellement ce morceau de code pour rendre une liste:

<ul ng-cloak>
    <div ng-repeat="n in list">
        <li><a href="{{ n[1] }}">{{ n[0] }}</a></li>
        <li class="divider"></i>
    </div>
    <li>Additional item</li> 
</ul>

cependant, l'élément <div> provoque des défauts de rendu très mineurs sur certains navigateurs. J'aimerais savoir s'il y a un moyen de faire la répétition ng sans le contenant div, ou une autre méthode pour obtenir le même effet.

87
demandé sur nehz 2012-10-12 15:05:30

6 réponses

comme Andy Joslin dit qu'ils travaillaient sur le commentaire basé ng-répétitions mais apparemment il y avait trop de problèmes de navigateur . Heureusement AngularJS 1.2 ajoute un support intégré pour répéter sans ajouter d'éléments enfants avec les nouvelles directives ng-repeat-start et ng-repeat-end .

voici un petit exemple pour ajouter pagination Bootstrap :

<ul class="pagination">
  <li>
    <a href="#">&laquo;</a>
  </li>
  <li ng-repeat-start="page in [1,2,3,4,5,6]"><a href="#">{{page}}</a></li>
  <li ng-repeat-end class="divider"></li>
  <li>
    <a href="#">&raquo;</a>
  </li>
</ul>

un exemple complet peut être trouvé ici .

John Lindquist a également un tutoriel vidéo de ce plus à son excellent egghead.io page .

100
répondu jmagnusson 2014-07-24 15:23:02

KnockoutJS containerless binding syntax""

s'il vous Plaît garder avec moi une seconde: KnockoutJS propose une ultra-option pratique de l'aide d'un containerless syntaxe de liaison pour ses foreach liaison comme mentionné dans la Note 4 de la section foreach liaison de la documentation. http://knockoutjs.com/documentation/foreach-binding.html

comme l'illustre l'exemple de documentation Knockout, vous pouvez écrire votre reliure en KnockoutJS comme ceci:

<ul>
    <li class="header">Header item</li>
    <!-- ko foreach: myItems -->
        <li>Item <span data-bind="text: $data"></span></li>
    <!-- /ko -->
</ul>

je pense Qu'il est assez malheureux AngularJS N'offre pas ce type de syntaxe.


Angulaire ng-repeat-start et ng-repeat-end

dans la façon AngularJS de résoudre ng-repeat problèmes, les échantillons que je rencontre sont du type jmagnusson posté dans sa réponse (utile).

<li ng-repeat-start="page in [1,2,3,4,5]"><a href="#">{{page}}</a></li>
<li ng-repeat-end></li>

ma pensée originale en voyant ceci la syntaxe est: vraiment? Pourquoi L'angle force-t-il toute cette marge supplémentaire que je ne veux rien à voir avec et qui est tellement plus facile à Knockout? Mais alors le commentaire d'hitautodestruct dans la réponse de jmagnusson a commencé à me faire me demander: qu'est-ce qui est généré avec ng-repeat-start et ng-repeat-end sur des étiquettes séparées?


d'Une façon plus propre d'utiliser ng-repeat-start et ng-repeat-end

après enquête sur l'assertion de hitautodestruct, ajoutant ng-repeat-end sur une étiquette séparée est exactement ce que je pas veux faire dans la plupart des cas, parce qu'il génère des éléments totalement inutiles: dans ce cas, <li> articles avec rien en eux. La liste paginée de Bootstrap 3 affiche les éléments de la liste de sorte qu'il semble que vous n'avez pas généré d'éléments superflus, mais lorsque vous inspectez le html généré, ils sont là.

Heureusement , vous n'avez pas besoin de faire beaucoup de avoir une solution plus propre et une quantité plus courte de html: vient de mettre la déclaration ng-repeat-end sur la même étiquette html qui a le ng-repeat-start .

<ul class="pagination">
  <li>
    <a href="#">&laquo;</a>
  </li>    
  <li ng-repeat-start="page in [1,2,3,4,5]" ng-repeat-end><a href="#"></a></li>
  <li>
    <a href="#">&raquo;</a>
  </li>
</ul>

cela donne 3 avantages:

  1. moins de balises html pour écrire
  2. inutile, les tags vides ne sont pas générés par angulaire
  3. quand le tableau à répéter est vide, la balise avec ng-repeat ne sera pas générer, en vous donnant le même avantage que la reliure containerless de Knockout vous donne à cet égard

mais il y a encore un moyen plus propre

après un nouvel examen des commentaires en github sur cette question pour Angular, https://github.com/angular/angular.js/issues/1891 ,

vous n'avez pas besoin d'utiliser ng-repeat-start et ng-repeat-end pour obtenir les mêmes avantages. Au lieu de cela, bifurquant à nouveau l'exemple de jmagnusson, nous pouvons simplement aller:

<ul class="pagination">
  <li>
    <a href="#">&laquo;</a>
  </li>
  <li ng-repeat="page in [1,2,3,4,5,6]"><a href="#">{{page}}</a></li>
  <li>
    <a href="#">&raquo;</a>
  </li>
</ul>

alors quand utiliser ng-repeat-start et ng-repeat-end ? Selon la "documentation angulaire , à

...répéter une série d'éléments au lieu d'un seul élément parent...

assez parlé, montrer quelques exemples!

assez bon; ce jsbin marche à travers cinq exemples de que se passe-t-il lorsque vous n'utilisez pas ng-repeat-end sur la même étiquette?

http://jsbin.com/eXaPibI/1 /

30
répondu mg1075 2014-01-30 14:32:24

ngRepeat peut ne pas être suffisant, cependant vous pouvez combiner cela avec une directive personnalisée. Vous pouvez déléguer la tâche d'ajouter des articles de diviseur au code si vous ne vous gênez pas un peu de jQuery.

 <li ng-repeat="item in coll" so-add-divide="your exp here"></li>

une directive aussi simple n'a pas vraiment besoin d'une valeur d'attribut mais peut vous donner beaucoup de possibilités comme l'ajout conditionnel d'un diviseur selon l'indice, La longueur, etc ou quelque chose de complètement différent.

6
répondu orcun 2012-10-12 20:58:46

j'ai récemment eu le même problème en ce que j'ai dû répéter une collection arbitraire de travées et d'images - avoir un élément autour d'eux n'était pas une option - il y a une solution simple cependant, créer une directive" null":

app.directive("diNull", function() {
        return {
            restrict: "E",
            replace: true,
            template: ""
        };
    });

vous pouvez alors utiliser une répétition sur cet élément, où élément.url pointe vers le modèle de cet élément:

<di-null ng-repeat="element in elements" ng-include="element.url" ></di-null>

cela répétera n'importe quel nombre de gabarits différents avec aucun conteneur autour d'eux

Note: hmm j'aurais juré aveugle cela a enlevé l'élément di-null lors du rendu, mais en le vérifiant à nouveau il ne le fait pas...toujours résolu mes problèmes d'implantation...curioser et curioser...

3
répondu Raphael Huerzeler 2013-09-17 12:48:41

il y a une restriction de la directive comment, mais ngRepeat ne la supporte pas (puisqu'elle a besoin d'un élément à répéter).

je pense que j'ai vu l'équipe angulaire dire qu'ils travailleraient sur le commentaire ng-répétitions, mais je ne suis pas sûr. Vous devriez lui ouvrir un numéro sur le repo. http://github.com/angular/angular.js

1
répondu Andrew Joslin 2012-10-12 12:04:00

il n'y a pas de façon magique angulaire de faire cela, pour votre cas vous pouvez le faire, pour obtenir du HTML valide, si vous utilisez Bootstrap. Vous obtiendrez alors le même effet que l'ajout du li.diviseur

créer une classe:

span.divider {
 display: block;
}

changez maintenant votre code pour ceci:

<ul ng-cloak>
 <li div ng-repeat="n in list">
    <a href="{{ n[1] }}">{{ n[0] }}</a>
    <span class="divider"></span>
 </li>
 <li>Additional item</li>
</ul>
0
répondu Eduardo in Norway 2015-05-13 11:49:18