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, le <div>
L'élément provoque des défauts de rendu très mineurs sur certains navigateurs. J'aimerais savoir s'il existe un moyen de faire la répétition ng sans le conteneur div ou une méthode alternative pour obtenir le même effet.
Comme Andy Joslin a déclaré qu'ils travaillaient sur des répétitions de commandes basées sur des commentaires mais apparemment, il y avait trop de problèmes de navigateur . Heureusement, AngularJS 1.2 ajoute la prise en charge intégrée permettant de 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="#">«</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="#">»</a>
</li>
</ul>
Un exemple complet de travail peut être trouvé ici .
John Lindquist a également un tutoriel vidéo à ce sujet sur son excellente page egghead.io .
Veuillez en garder une seconde: KnockoutJS offre une option extrêmement pratique consistant à utiliser une syntaxe de liaison sans conteneur pour sa liaison foreach
, comme indiqué dans la note 4 de la documentation de liaison foreach
. http://knockoutjs.com/documentation/foreach-binding.html
Comme l'illustre l'exemple de la documentation Knockout, vous pouvez écrire votre liaison dans 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 plutôt regrettable que AngularJS ne propose pas ce type de syntaxe.
ng-repeat-start
et ng-repeat-end
Dans la manière AngularJS de résoudre ng-repeat
_ problèmes, les exemples 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 initiale en voyant cette syntaxe est: vraiment? Pourquoi Angular oblige-t-il tout ce balisage supplémentaire pour lequel je ne veux rien avoir à faire et qui est tellement plus facile dans Knockout? ng-repeat-start et ng-repeat-end sur des balises distinctes?
ng-repeat-start
et ng-repeat-end
Après enquête sur l'assertion de hitautodestruct, ajout de ng-repeat-end
sur une balise séparée correspond exactement à ce que je voudrais ne pas faire dans la plupart des cas, car il génère des éléments totalement inutilisables: dans ce cas, <li>
articles ne contenant rien. Bootstrap 3 modélise les éléments de la liste pour donner l'impression que vous n'avez pas généré d'éléments superflus, mais lorsque vous inspectez le code HTML généré, ils sont présents.
Heureusement , vous n'avez pas besoin de faire beaucoup pour avoir une solution plus propre et une quantité plus courte de html: il suffit de mettre le ng-repeat-end
déclaration sur la même balise HTML qui a le ng-repeat-start
_ .
<ul class="pagination">
<li>
<a href="#">«</a>
</li>
<li ng-repeat-start="page in [1,2,3,4,5]" ng-repeat-end><a href="#"></a></li>
<li>
<a href="#">»</a>
</li>
</ul>
Cela donne 3 avantages:
ng-repeat
ne sera pas généré, ce qui vous donnera le même avantage que la liaison sans conteneur de Knockout vous offre à cet égardAprès avoir passé en revue les commentaires de github sur ce problème 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, reprenons l'exemple de Jmagnusson, nous pouvons simplement aller:
<ul class="pagination">
<li>
<a href="#">«</a>
</li>
<li ng-repeat="page in [1,2,3,4,5,6]"><a href="#">{{page}}</a></li>
<li>
<a href="#">»</a>
</li>
</ul>
Alors, quand utiliser ng-repeat-start
et ng-repeat-end
? Selon le documentation angulaire , à
... répétez une série d'éléments au lieu d'un seul élément parent ...
C'est suffisant; jsbin présente cinq exemples de ce qui se passe quand vous faites et quand vous n’utilisez pas ng-repeat-end
sur la même étiquette.
ngRepeat peut ne pas suffire, mais vous pouvez combiner cela avec une directive personnalisée. Vous pouvez déléguer la tâche d'ajouter des éléments de division au code si un peu de jQuery ne vous dérange pas.
<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 en fonction de l'index, de la longueur, etc. ou de quelque chose de complètement différent.
J'ai eu récemment le même problème en ce sens que je devais répéter une collection arbitraire de plages et d'images. Avoir un élément autour d'eux n'était pas une option. Il existe une solution simple, mais créez une directive "null":
app.directive("diNull", function() {
return {
restrict: "E",
replace: true,
template: ""
};
});
Vous pouvez ensuite utiliser une répétition sur cet élément, où element.url pointe vers le modèle pour 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 modèles différents sans aucun conteneur autour d'eux
Remarque: hmm, j'aurais peut-être juré à l'aveugle de supprimer l'élément di-null lors du rendu, mais le relire à nouveau ne résout pas ... toujours mes problèmes de mise en page bien ... curioser et curioser ...
Il existe une restriction de directive de commentaire, mais ngRepeat ne la prend pas en charge (car elle nécessite un élément à répéter).
Je pense avoir vu l’équipe angular dire qu’elle travaillerait sur les répétitions de commentaires, mais je ne suis pas certaine. Vous devriez ouvrir un problème à ce sujet dans le référentiel. http: //github.com/angular/angular.js
Il n'y a pas de moyen magique Angular). Si vous utilisez Bootstrap, vous pouvez le faire pour obtenir du code HTML valide. Vous obtiendrez alors le même effet que d'ajouter le paramètre li.divider.
Créer une classe:
span.divider {
display: block;
}
Maintenant changez votre code en 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>
pour une solution qui fonctionne vraiment
html
<remove ng-repeat-start="itemGroup in Groups" ></remove>
html stuff in here including inner repeating loops if you want
<remove ng-repeat-end></remove>
ajouter une directive angular.js
//remove directive
(function(){
var remove = function(){
return {
restrict: "E",
replace: true,
link: function(scope, element, attrs, controller){
element.replaceWith('<!--removed element-->');
}
};
};
var module = angular.module("app" );
module.directive('remove', [remove]);
}());
pour une brève explication,
ng-repeat se lie au <remove>
élément et boucles comme il se doit, et comme nous avons utilisé ng-repeat-start/ng-repeat-end, il boucle un bloc de code HTML non seulement un élément.
alors la directive de suppression personnalisée place le <remove>
début et fin des éléments avec <!--removed element-->