2012-04-11 6 views
13

Se il mio elenco è vuoto, voglio uscita questo:modelli Moustache: come uscita un blocco solo una volta per le liste non vuote

<div id="some-id"> 
</div> 

Se la mia lista non è vuota, voglio uscita questo:

<div id="some-id"> 
    <ul> 
    <li>Item 1</li> 
    <li>Item 2</li> 
    <li>etc</li> 
    </ul> 
</div> 

si noti che in uscita ho le <ul> e </ul> tag al massimo una volta, e solo se l'elenco non è vuoto.

Il seguente codice è vicino a come vorrei farlo in PHP, ma è ovviamente sbagliato:

<div id="some-id"> 
{{#items}} 
    <ul> 
{{/items}} 

{{#items}} 
    <li>{{name}}</li> 
{{/items}} 

{{#items}} 
    </ul> 
{{/items}} 
</div> 

Se items è una lista 3 articolo, ho intenzione di ottenere 3 <ul> 's - ovviamente non quello che voglio

Mi rendo conto che potrei impostare qualche altra chiave come una bandiera booleana (hasItems, forse), ma questo sembra ridondante.

Esiste un modo più elegante per emettere un blocco una sola volta per un elenco non vuoto?

+1

A mio parere (e 4 anni dopo) non esiste ancora una soluzione soddisfacente per questo problema in "baffi" afaik. avremmo bisogno del contrario di una "sezione invertita" - una sezione che esegue il rendering ** solo una volta ** se il valore della chiave è true (la chiave esiste, la lista non vuota, il valore della chiave è vero, ...)! –

risposta

4

È possibile utilizzare non-false values di una sezione. name avrebbe dovuto essere un oggetto all'interno di items

data = { 'items' : { 'name' : ["Item 1", "Item 2", "etc"] } }; 

È modello sarà simile:

<div id="some-id"> 
    {{#items}} 
    <ul> 
     {{#name}} 
     <li>{{.}}</li> 
     {{/name}} 
    </ul> 
    {{/items}} 
</div> 

Ecco un esempio sul jsFiddle che mostra il rendering di un oggetto items con i nomi e senza - http://jsfiddle.net/maxbeatty/fpQwk/

+0

Hmmm. Questa è un'idea interessante. Probabilmente rappresenterei i dati come '{'itemsContainer': {'items': [{'name': 'item 1'}, {'name': 'item 2'}, {'name': 'etc' }]}}; '. Grazie! –

+5

dovendo cambiare la struttura dei dati solo perché il rendering del template non supporta il caso specifico mi sembra molto limitante. – ElLocoCocoLoco

+0

se non si desidera modificare la struttura dati, modificare il motore di template – maxbeatty

13

Se non si desidera o non è possibile riformattare i dati o il motore dei modelli, è anche possibile controllare lo items.length prima di rendere i tag <ul>. Alcune persone disapprovano questo, ma è sicuramente un'alternativa alla risposta di Max.

{{#items.length}} 
    <ul> 
     {{items}} 
      <li>{{name}}</li> 
     {{/items}} 
    </ul> 
{{/items.length}} 
+4

Nice. Tuttavia, funzionerebbe solo con un'implementazione JavaScript di JavaScript, giusto? –

+1

... implementazione JavaScript di * Moustache * ... –

+1

sì, ma la maggior parte delle lingue ha una sorta di proprietà o metodo che è possibile controllare per ottenere la lunghezza dell'array ... con java, è '.size', ecc. Pertanto, _should_ tradurrà nella maggior parte delle lingue. – broox

1

Le altre due risposte non funzionano per l'implementazione Ruby di Moustache. La mia soluzione era di inviare un parametro aggiuntivo come parte del contesto del modello; per esempio.

template = <<EOF 
{{#has_items}} 
<ul> 
    {{#items}} 
     <li>{{.}}</li> 
    {{/items}} 
</ul> 
{{/has_items}} 
EOF 
items = ['one', 'two', 'three'] 
context = { items: items, has_items: items.any? } 
Mustache.render(template, context)