Ng-repeat angular append une rangée bootstrap tous les 3 ou 4 cols

Je cherche le bon modèle pour injecter une classe de ligne bootstrap toutes les 3 colonnes. J’ai besoin de ça parce que cols n’a pas de hauteur fixe (et je ne veux pas en corriger une), donc ça casse mon design!

Voici mon code:

...

Mais il affiche uniquement un produit dans chaque ligne. Ce que je veux comme résultat final est:

 
...
...
...
...
...
...

Puis-je y parvenir uniquement avec le motif ng-repeat (sans directive ni contrôleur)? Les documents introduisent ng-repeat-start et ng-repeat-end mais je ne peux pas comprendre comment l’utiliser c’est ce cas d’utilisation! Je pense que c’est quelque chose que nous utilisons souvent dans les modèles bootstrap! ? Merci

La réponse la plus votée, bien qu’efficace, n’est pas ce que je considérerais comme la voie angular, ni d’utiliser les propres classes de bootstrap destinées à gérer cette situation. Comme @claies l’a mentionné, la classe .clearfix est destinée à de telles situations. À mon avis, la mise en œuvre la plus propre est la suivante:

 

{{product.title}}

Cette structure évite l’indexation désordonnée du tableau de produits, permet une notation par point propre et utilise la classe clearfix pour son usage prévu.

Je sais que c’est un peu tard mais ça pourrait quand même aider quelqu’un. Je l’ai fait comme ça:

 
{{products[$index]}}
{{products[$index + 1]}}
{{products[$index + 2]}}

jsfiddle

Ok, cette solution est beaucoup plus simple que celles déjà présentes, et permet différentes largeurs de colonne pour différentes largeurs de périphérique.

 
... your content here ...

Notez que la partie % 6 est supposée être égale au nombre de colonnes résultantes. Donc, si sur la colonne vous avez la classe col-lg-2 il y aura 6 colonnes, donc utilisez ... % 6 .

Cette technique (à l’exclusion du ng-if ) est en fait documentée ici: docs Bootstrap

Bien que ce que vous voulez accomplir puisse être utile, il y a une autre option qui, à mon avis, pourrait vous échapper, qui est beaucoup plus simple.

Vous avez raison, les tables Bootstrap agissent étrangement lorsque vous avez des colonnes qui ne sont pas de hauteur fixe. Cependant, il existe une classe de bootstrap créée pour lutter contre ce problème et effectuer des réinitialisations réactives .

créez simplement un

vide avant le début de chaque nouvelle ligne pour permettre aux flottants de se réinitialiser et aux colonnes de revenir à leurs positions correctes.

voici un bootply .

Merci pour vos suggestions, vous êtes sur la bonne voie!

Allons-y pour une explication complète:

  • Par défaut, AngularJS http get retourne un object

  • Donc, si vous voulez utiliser la fonction @Ariel Array.prototype.chunk, vous devez d’abord transformer l’object en un tableau.

  • Et puis, pour utiliser la fonction de bloc IN YOUR CONTROLLER sinon, si elle est utilisée directement dans ng-repeat, cela vous amènera à une erreur infdig . Le contrôleur final ressemble à:

     // Initialize products to empty list $scope.products = []; // Load products from config file $resource("/json/shoppinglist.json").get(function (data_object) { // Transform object into array var data_array =[]; for( var i in data_object ) { if (typeof data_object[i] === 'object' && data_object[i].hasOwnProperty("name")){ data_array.push(data_object[i]); } } // Chunk Array and apply scope $scope.products = data_array.chunk(3); }); 

Et HTML devient:

 

D’un autre côté, j’ai décidé de retourner directement un tableau [] au lieu d’un object {} à partir de mon fichier JSON. De cette façon, le contrôleur devient (veuillez noter la syntaxe spécifique isArray: true ):

  // Initialize products to empty list $scope.products = []; // Load products from config file $resource("/json/shoppinglist.json").query({method:'GET', isArray:true}, function (data_array) { $scope.products = data_array.chunk(3); }); 

HTML rest le même que ci-dessus.

OPTIMISATION

La dernière question en suspens est la suivante: comment le rendre 100% AngularJS sans étendre le tableau javascript avec la fonction chunk … si certaines personnes souhaitent nous montrer si ng-repeat-start et ng-repeat-end sont la solution. . Je suis curieux 😉

LA SOLUTION D’ANDREW

Grâce à @Andrew, nous soaps maintenant que l’ajout d’une classe clearfix bootstrap tous les trois éléments (ou peu importe le nombre) corrige le problème d’affichage de la hauteur des différents blocs.

Donc HTML devient:

 
My product descrition with {{product.property}}

Et votre contrôleur rest très souple avec la fonction chunck supprimée :

 // Initialize products to empty list $scope.products = []; // Load products from config file $resource("/json/shoppinglist.json").query({method:'GET', isArray:true}, function (data_array) { //$scope.products = data_array.chunk(3); $scope.products = data_array; }); 

Basé sur la solution Alpar, utilisant uniquement des modèles avec ng-repeat anidé. Fonctionne avec des lignes à la fois pleines et partiellement vides:

 
{{product}}

JSFiddle

Vous pouvez le faire sans directive, mais je ne suis pas sûr que ce soit la meilleure façon. Pour ce faire, vous devez créer un tableau de tableaux à partir des données que vous souhaitez afficher dans la table, puis utiliser 2 ng-repeat pour parcourir le tableau.

pour créer le tableau pour l’affichage, utilisez cette fonction comme celle products.chunk (3)

 Array.prototype.chunk = function(chunkSize) { var array=this; return [].concat.apply([], array.map(function(elem,i) { return i%chunkSize ? [] : [array.slice(i,i+chunkSize)]; }) ); } 

et puis faire quelque chose comme ça en utilisant 2 ng-repeat

 
{{item}}

Je viens de faire une solution en travaillant uniquement dans un modèle. La solution est

   
{{product.foo}}

Point utilise des données deux fois, l’une pour une boucle extérieure. Des balises de scope supplémentaires restront, mais cela dépend de la manière dont vous faites le compromis.

Si c’est une disposition en 3 colonnes, ça va être comme

   
{{product.foo}}

Honnêtement je voulais

 $index 

Bien que cela n'ait pas marché.

Juste une autre petite amélioration à propos de @Duncan et les autres réponses basées sur l’élément clearfix. Si vous voulez que le contenu puisse être cliqué, vous aurez besoin d’un z-index > 0 ou clearfix chevauchera le contenu et gérera le clic.

C’est l’ exemple qui ne fonctionne pas (vous ne pouvez pas voir le pointeur du curseur et cliquer ne fera rien):

 

{{product.title}}

Alors que c’est le fixe :

 

{{product.title}}

J’ai ajouté z-index: 1 pour faire remonter le contenu par-dessus le clearfix et j’ai supprimé le div du conteneur en utilisant à la place ng-repeat-start et ng-repeat-end (disponible chez AngularJS 1.2) ne fonctionne pas.

J’espère que cela t’aides!

Mettre à jour

Plunker: http://plnkr.co/edit/4w5wZj

j’ai résolu cela en utilisant ng-class

 
{{item.name}}

Le meilleur moyen d’appliquer une classe est d’utiliser ng-class. Elle peut être utilisée pour appliquer des classes en fonction de certaines conditions.

 

et ensuite dans votre contrôleur

 $scope.getRowClass = function(index){ if(index%3 == 0){ return "row"; } } 

Petite modification de la solution de @alpar

 
{{products[idx+$parent.$index]}}

jsfiddle

Après avoir combiné plusieurs réponses et suggestions ici, voici ma dernière réponse, qui fonctionne bien avec flex , ce qui nous permet de créer des colonnes de hauteur égale, de vérifier le dernier index et de ne pas répéter le code HTML interne. Il n’utilise pas clearfix :

 
{{ product.name }}

Il va sortir quelque chose comme ceci:

 
Product Name
Product Name
Product Name
Product Name
Product Name
Product Name

Cela a fonctionné pour moi, pas d’épissage ou quelque chose requirejs:

HTML

 

JavaScript

 var columnsPerRow = 4; $scope.rows = function() { return new Array(columnsPerRow); }; $scope.indexInRange = function(columnIndex,rowIndex) { return columnIndex >= (rowIndex * columnsPerRow) && columnIndex < (rowIndex * columnsPerRow) + columnsPerRow; }; 

Born Solutions son meilleur, juste besoin d’un peu de tweek pour répondre aux besoins, j’avais différentes solutions réactives et un peu changé

 

Essayez cet exemple

            
{{products[$index]}}
{{products[$index + 1]}}
{{products[$index + 2]}}

En s’appuyant sur la réponse d’Alpar, voici un moyen plus généralisé de diviser une seule liste d’éléments en plusieurs conteneurs (lignes, colonnes, compartiments, etc.):

 
{{item.name}}

pour une liste de 10 éléments, génère:

 
Item 1
Item 4
Item 7
Item 10
Item 2
Item 5
Item 8
Item 3
Item 6
Item 9

Le nombre de conteneurs peut être rapidement codé dans une fonction de contrôleur:

JS (ES6)

 $scope.rowList = function(rows) { return Array(rows).fill().map((x,i)=>i); } $scope.rows = 2; 

HTML

 
...

Cette approche évite de dupliquer le balisage d’élément ( {{item.name}} dans ce cas) dans le modèle source – ce n’est pas un gain énorme pour un intervalle simple, mais pour une structure DOM plus complexe eu), cela aide à garder le modèle SEC.