Ng-repeat angular aggiunge una riga di bootstrap ogni 3 o 4 colonne

Sto cercando il modello giusto per iniettare una class di righe bootstrap ogni 3 colonne. Ho bisogno di questo perché i cols non hanno un’altezza fissa (e non voglio sistemarne una), quindi si rompe il mio disegno!

Ecco il mio codice:

...

Ma mostra solo un prodotto in ogni riga. Quello che voglio come risultato finale è:

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

Posso ottenere questo risultato con il solo pattern ng-repeat (senza direttiva o controller)? I documenti introducono ng-repeat-start e ng-repeat-end ma non riesco a capire come usarlo è questo caso d’uso! Mi sembra che questo sia qualcosa che usiamo spesso nei template bootstrap! ? Grazie

La risposta votata in alto, seppur efficace, non è quella che considererei il modo angular, né sta utilizzando le proprie classi di bootstrap che sono pensate per affrontare questa situazione. Come @claies menzionato, la class .clearfix è pensata per situazioni come queste. Secondo me, l’implementazione più pulita è la seguente:

 

{{product.title}}

Questa struttura evita l’indicizzazione disordinata dell’array di prodotti, consente la notazione di punti puliti e utilizza la class clearfix per lo scopo previsto.

So che è un po ‘tardi ma potrebbe ancora aiutare qualcuno. L’ho fatto in questo modo:

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

jsfiddle

Va bene, questa soluzione è molto più semplice di quelle già qui e consente diverse larghezze di colonna per diverse larghezze del dispositivo.

 
... your content here ...

Si noti che la parte % 6 dovrebbe essere uguale al numero di colonne risultanti. Quindi se sull’elemento colonna hai la class col-lg-2 ci saranno 6 colonne, quindi usa ... % 6 .

Questa tecnica (escluso il ng-if ) è in realtà documentata qui: documenti Bootstrap

Anche se ciò che si vuole realizzare può essere utile, c’è un’altra opzione che ritengo si possa ignorare che è molto più semplice.

Sei corretto, le tabelle Bootstrap agiscono stranamente quando hai colonne che non sono altezze fisse. Tuttavia, esiste una class bootstrap creata per combattere questo problema ed eseguire ripristini sensibili .

è sufficiente creare un

vuoto prima dell’inizio di ogni nuova riga per consentire il ripristino dei float e il ripristino delle colonne nelle loro posizioni corrette.

ecco un bootply .

Grazie per i tuoi suggerimenti, mi hai preso sulla buona strada!

Andiamo per una spiegazione completa:

  • Per impostazione predefinita, la query get di AngularJS http restituisce un object

  • Quindi, se vuoi utilizzare la funzione @Ariel Array.prototype.chunk, devi prima trasformare l’object in un array.

  • E poi usare la funzione chunk IN YOUR CONTROLLER altrimenti se usata direttamente in ng-repeat, ti porterà ad un errore di infdig . Il controller finale sembra:

     // 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); }); 

E l’HTML diventa:

 

Dall’altro lato, ho deciso di restituire direttamente un array [] invece di un object {} dal mio file JSON. In questo modo, il controller diventa (si prega di notare syntax specifica 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); }); 

L’HTML rimane lo stesso di sopra.

OTTIMIZZAZIONE

L’ultima domanda in sospeso è: come renderlo 100% AngularJS senza estendere l’array javascript con la funzione chunk … se alcune persone sono interessate a mostrarci se ng-repeat-start e ng-repeat-end sono la strada da percorrere .. . Sono curioso 😉

ANDREW’S SOLUTION

Grazie a @Andrew, ora sappiamo che aggiungere una class di clearfix bootstrap ogni tre (o qualunque numero) elemento corregge il problema di visualizzazione dall’altezza del blocco differente.

Quindi l’HTML diventa:

 
My product descrition with {{product.property}}

E il tuo controller rimane abbastanza morbido con la funzione chunck rimossa :

 // 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; }); 

Basato sulla soluzione di Alpar, utilizzando solo modelli con ng-ripetizione anidata. Funziona con entrambe le righe piene e parzialmente vuote:

 
{{product}}

JSFiddle

Puoi farlo senza una direttiva, ma non sono sicuro che sia il modo migliore. Per fare ciò è necessario creare una matrice di array dai dati che si desidera visualizzare nella tabella e, successivamente, utilizzare 2 ng-repeat per scorrere l’array.

per creare l’array per la visualizzazione usa questa funzione come 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)]; }) ); } 

e poi fai qualcosa del genere usando 2 ng-repeat

 
{{item}}

Ho appena fatto una soluzione di esso lavorando solo in modello. La soluzione è

   
{{product.foo}}

Point sta usando i dati due volte, uno è per un ciclo esterno. I tag extra span rimarranno, ma dipende da come vali.

Se si tratta di un layout a 3 colonne, sarà come

   
{{product.foo}}

Onestamente, volevo

 $index 

Anche se non ha funzionato.

Solo un altro piccolo miglioramento sulla risposta @Duncan e le altre risposte basate sull’elemento clearfix. Se vuoi rendere il contenuto cliccabile avrai bisogno di uno z-index > 0 su di esso o di un clearfix che si sovrapporrà al contenuto e gestirà il clic.

Questo è l’ esempio non funziona (non puoi vedere il puntatore del cursore e fare clic non farà nulla):

 

{{product.title}}

Mentre questo è quello fisso :

 

{{product.title}}

Ho aggiunto z-index: 1 per far alzare il contenuto sulla clearfix e ho rimosso il contenitore div usando invece ng-repeat-start e ng-repeat-end (disponibile da AngularJS 1.2) perché ha fatto z-index non funziona.

Spero che questo ti aiuti!

Aggiornare

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

Ho risolto questo usando ng-class

 
{{item.name}}

Il modo migliore per applicare una class è usare ng-class. Può essere usato per applicare classi in base ad alcune condizioni.

 

e poi nel tuo controller

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

Piccola modifica nella soluzione di @alpar

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

jsfiddle

Dopo aver combinato molte risposte e suggerimenti, questa è la mia risposta finale, che funziona bene con flex , che ci consente di creare colonne con uguale altezza, controlla anche l’ultimo indice e non è necessario ripetere l’HTML interno. Non usa la clearfix :

 
{{ product.name }}

Produrrà qualcosa come questo:

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

Questo ha funzionato per me, senza splicing o nulla richiesto:

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 è la migliore, solo bisogno di un po ‘di tweek per soddisfare le esigenze, ho avuto diverse soluzioni reattive e cambiato un po’

 

Prova questo esempio

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

Basandosi sulla risposta di Alpar, ecco un modo più generalizzato per dividere un singolo elenco di elementi in più contenitori (righe, colonne, bucket, qualunque cosa):

 
{{item.name}}

per un elenco di 10 articoli, genera:

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

Il numero di contenitori può essere codificato rapidamente in una funzione controller:

JS (ES6)

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

HTML

 
...

Questo approccio evita di duplicare il markup dell’elemento ( {{item.name}} in questo caso) nel modello sorgente – non una vincita enorme per una semplice span, ma per una struttura DOM più complessa (che io aveva) questo aiuta a mantenere il modello ASCIUTTO.