homeASCIIcasts

28: In Groups Of 

(view original Railscast)

Other translations: En

Other formats:

Written by Andrea Salicetti

Di seguito è un’applicazione che mostra una lista di task. I task sono visualizzati in una tabella in un unica colonna. Potremmo fare un miglior uso dello spazio usando più colonne, ma qual è il modo migliore per farlo? Rails fornisce un metodo chiamato in_groups_of, come estensione agli oggetti Array, che ci aiuta nel compito.

La nostra lista di task in una singola colonna.

La nostra lista di task in una singola colonna.

Per mostrare come funziona in_groups_of, lo vedremo in azione dalla console.

>> a = (1..12).to_a
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
>> a.in_groups_of(4)
=> [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
>> a.in_groups_of(3)
=> [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]

Nella prima riga abbiamo creato un array di dodici elementi mediante un range. Il metodo in_groups_of usato passando un singolo argomento (intero positivo) restituisce un array di array, ciascuno contenente n elementi, dove n è il valore del parametro attuale passato. Nel codice abbiamo diviso l’array prima in tre gruppi di quattro elementi e poi in quattro gruppi di tre elementi. (Si noti che in_groups_of restituisce una copia dell’array originale, non lo modifica.)

Mostrare i nostri task in colonna

Ora che sappiamo come usare il metodo in_groups_of, possiamo sfruttarlo nel codice della nostra vista per mostrare la lista dei task su più colonne. La parte significative della vista index attualmente appare così:

<table>
    <% @tasks.each do |task| %>
    <tr>
      <td><%= task.name %></td>
    </tr>
    <% end %>
</table>

La cambiamo in questo modo:

<table>
    <% @tasks.in_groups_of(4) do |tasks| %>
    <tr>
      <% tasks.each do |task| %>
      <td><%= task.name %></td>
      <% end %>
    </tr>
    <% end %>
</table>

Si può usare un blocco assieme al in_groups_of, in modo tale da dividere i nostri task in gruppi di quattro elementi, stampare un tag di apertura tr, poi iterare su ogni task del gruppo e stamparlo fra tag td e infine chiudere il tag tr. Il risultato è visibile qui sotto:

I nostri task sono ora mostrati su quattro colonne.

I nostri task sono ora mostrati su quattro colonne come volevamo, ma non è ancora abbastanza. Poichè stavamo mostrando dodici task a gruppi di quattro, abbiamo riempito tutte le colonne e le righe. Se tuttavia aggiungessimo un altro paio di task e ricaricassimo la pagina, accadrebbe la seguente cosa:

La nostra applicazione va in errore se il numero di task non è multiplo della cardinalità dei grouppi.

Possiamo capirne la ragione se torniamo indietro alla console e proviamo a dividere il nostro array di dodici elementi a gruppi di cinque.

>> a = (1..12).to_a
>> a.in_groups_of(5)
=> [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, nil, nil, nil]]

Se non ci sono abbastanza elementi per riempire l’ultimo array, in_groups_of usa nil per riempire l’ultimo gruppo. Per evitare ciò, passiamo un secondo argomento al metodo. Se il secondo argomento (booleano) passato è false, l’ultimo array sarà più corto degli altri; se anzichè un booleano passassimo un altro valore come secondo argomento, quel valore verrebbe utilizzato per riempire (eventualmente) l’ultimo array.

>> a.in_groups_of(5, false)
=> [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12]]
>> a.in_groups_of(5, 0)
=> [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 0, 0, 0]]
>> 

Se dunque aggiungiamo false come secondo argomento al nostro in_groups_of presente in vista, la pagina verrà mostrata indipendentemente dal numero di task presenti.

Ora la nostra applicazione può gestire un numero qualunque di task.