2013-07-23 4 views
5

voglio scrivere 4 colonne in una riga come questain mezzo al mondo, come si può scrivere th: ciascuno per combinare righe e colonne?

<div class="row"> 
    <div class="span3">Something</div> 
    <div class="span3">Something</div> 
    <div class="span3">Something</div> 
    <div class="span3">Something</div> 
</div> 
<div class="row"> 
    <div class="span3">Something</div> 
    <div class="span3">Something</div> 
    <div class="span3">Something</div> 
    <div class="span3">Something</div> 
</div> 

dimensioni dei dati sono dinamici, in modo che possa essere di 4, 8 o più. questo viene archiviato in un altro motore di template

{{#each list}} 
    {{#if @index % 4 == 0}} 
    <div class="row"> 
    {{/if}} 
    <div class="span3">{{this.name}}</div> 
    {{#if @index % 4 == 0}} 
    </div> 
    {{/if}} 
{{/each}} 

Ma come posso archiviare questo thymeleaf? Non riesco a trovare la strada perché th:each è nel tag (<div class="row"> o <div class="span3">) come attributo.

risposta

10

MODELLO CODICE

List<String> data = new ArrayList<String>(); 
    data.add("1"); 
    data.add("2"); 
    data.add("3"); 
    data.add("4"); 
    data.add("5"); 
    data.add("6"); 
    data.add("7"); 
    data.add("8"); 

    model.addAttribute("datas", data); 

THYMELEAF vista Codice

<div th:each="data, row: ${datas}" th:with="numList=${#strings.listSplit('3,2,1,0', ',')}" th:if="${row.current} % 4 == 0" class="span3"> 
    <span th:each="num : ${numList}" th:with="dataIndex=(${row.index} - ${num})" th:text="${datas[dataIndex]}">data</span> 
</div> 

RISULTATO

<div class="span3"> 
    <span>1</span><span>2</span><span>3</span><span>4</span> 
</div> 
<div class="span3"> 
    <span>5</span><span>6</span><span>7</span><span>8</span> 
</div> 

ho usato un array per risolvere questo problema. Penso che troverai un modo migliore.

2

th: ciascuno può essere utilizzato praticamente su qualsiasi elemento. Quindi, qualcosa di simile:

<div class="row" th:each="row : ${rows}"> 
    <div class="span3" th:each="name : ${row.names}" th:text="${name}">Something</div> 
</div> 
+0

La raccolta devono essere divisi in due collezioni secondo la vostra risposta. ma solitamente i dati sono in una raccolta. Non penso che sia una buona idea cambiare il modello del lato server dal problema della presentazione. – Outsider

+0

È solo un esempio. Non si modifica il modello, si espone semplicemente un metodo sul modello che fornisce i dati come richiesto dalla vista. A mio avviso, NON si desidera tutta quella logica di visualizzazione nel modello. Penso che sia una cattiva pratica di progettazione. Quale delle risposte sopra è più facile da leggere e mantenere? IMO - metti la logica che divide l'elenco in insiemi di 4 in un metodo sul modello. Oppure hai un altro modello specifico della vista o qualcosa del genere ... Vedere http://www.codinghorror.com/blog/2008/05/understanding-model-view-controller.html – hubbardr

+1

grazie ... Penso che la soluzione sopra non sia chiara ma può gestire la mia situazione senza metodi aggiuntivi. Non sono d'accordo aggiungendo un metodo sul modello. Perché il modo di visualizzare i dati è solo il ruolo del livello di presentazione. Perché il modello ha tali methos aggiuntivi? e a volte non possiamo modificare i modelli. In effetti, penso che il programma tym deve essere aggiunto per questo metodo di aiuto. – Outsider

3

Ho appena creato un account qui per correggere la risposta accettata. La risposta accettata funziona alla grande fintanto che i "dati" che vengono passati sono una serie di interi consecutivi. Tuttavia, per farlo funzionare con qualsiasi tipo di struttura dati, "row.current" ha bisogno di cambiare per "row.count", come segue:

<div th:each="data, row: ${datas}" th:with="numList=${#strings.listSplit('3,2,1,0', ',')}" th:if="${row.count} % 4 == 0" class="span3"> 
    <span th:each="num : ${numList}" th:with="dataIndex=(${row.index} - ${num})" th:text="${datas[dataIndex]}">data</span> 
</div> 

Se si utilizza row.current, allora usa l'elemento reale la lista, che è grande nell'esempio mostrato, ma non così grande per qualsiasi altro tipo di struttura dei dati. Spero che questo ti aiuti.

EDIT:

devo perfezionare ulteriormente questo perché la risposta accettata anche non funziona se il numero di elementi nella lista non è divisibile per 4. Ecco una soluzione migliore (anche se probabilmente non perfetto) :

<div th:each="data, row: ${datas}" th:with="numList=${ {3,2,1,0} }" th:if="${row.count % 4 == 0 or row.last}" class="span3"> 
    <!-- Show all rows except the leftovers --> 
    <span th:each="num : ${numList}" th:with="dataIndex=(${row.index} - ${num})" th:if="${row.count % 4 == 0}" th:text="${datas[dataIndex]}">data</span> 
    <!-- Show the remainders (eg, if there are 9 items, the last row will have one item in it) --> 
    <span th:each="num : ${numList}" th:with="dataIndex=(${row.index} - ${num})" th:if="${row.last} and ${row.count % 4 != 0} and ${num &lt; row.count % 4}" th:text="${datas[dataIndex]}">data</span> 
</div> 

Questo può essere in grado di essere riscritta per eliminare una delle campate, ma devo passare ora.

+0

Questa è una risposta migliore. Piange davvero per qualche tipo di template annidato, dove si passa l'oggetto per il rendering. –

2

Anche questo può essere fatto utilizzando numbers.sequence. Impostare colCount a qualsiasi numero di colonne che desideri:

<th:block th:with="colCount=${4}"> 
    <div th:each="r : ${#numbers.sequence(0, datas.size(), colCount)}" class="row"> 
     <div th:each="c : ${#numbers.sequence(0, colCount - 1)}" th:if="${r + c &lt; datas.size()}" th:text="${datas.get(r + c)}" class="span3"></div> 
    </div> 
</th:block>