2012-01-05 14 views
27

Sto usando mustache.js per eseguire il rendering di un modello in javascript. Vorrei verificare se un elenco è vuoto o non nascondere il tag <h2> nell'esempio seguente. È possibile o è mustache.js troppo logico?Gestire una lista vuota in moustache.js

Questo è il modello:

<h2>Persons:</h2> 
<ul> 
    {{#persons}} 
    {{name}} 
    {{/persons}} 
</ul> 

e questo è il dato:

{ 
    "persons":[ 
    {"name": "max"}, 
    {"name": "tom"} 
    ] 
} 
+3

Il "dato" non è valido JSON. –

+2

Inoltre, potresti voler pensare di passare dal baffo al [manubrio] (http://handlebarsjs.com/), che può essere molto più aggraziato (oserei dire così?) Casi come questo. Questa non è la prima volta che qualcuno chiede (e gli è stato negato) e il test della lista vuota nei baffi: https://github.com/defunkt/mustache/issues/47. –

+0

@ MДΓΓБДLL Ti sto punendo per non aver fatto una risposta al tuo commento (che avrei votato volentieri) postandolo come risposta a me stesso e rubando i tuoi deliziosi punti karma. – andrewrk

risposta

26

Per mantenere il modello di logica-less, è possibile effettuare questo controllo prima del rendering del modello:

// assuming you get the JSON converted into an object 
var data = { 
    persons: [ 
     {name: "max"} 
     , {name: "tom"} 
    ] 
}; 
data.hasPersons = (data.persons.length > 0); 

Poi il modello sarà simile a questa:

<h2>Persons:</h2> 
{{#hasPersons}} 
<ul> 
    {{#persons}} 
    <li>{{name}}</li> 
    {{/persons}} 
</ul> 
{{/hasPersons}} 
+8

Per quanto questa sia una risposta corretta, penso che dover utilizzare questo tipo di approccio sia un segno di una vera debolezza nella sintassi di Moustache. Forse è OK fintanto che lo sviluppatore front-end (template) ha accesso al codice back-end (origine dati), ma se i due sono separati o il front-end dev è più uno sling HTML che un coder, diventerà carino impraticabile. –

+7

@TimHolt bene, ho sicuramente capito il tuo punto. Ci sono dei vantaggi però. Supponiamo che tu voglia testare unitamente questa parte della tua app. Con un motore di template senza logica, mi accontento di testare i dati solo da unità (prima che vengano alimentati a Moustache) e di non dover eseguire test di confronto a stringhe sul codice HTML risultante. Ora, se il mio modello avesse una logica (anche semplice come controllare .length> 0) sentirò la necessità di testare l'unità di quella logica, e quindi sarei costretto a fare il confronto delle stringhe o qualcosa come il selenio/robot doh . Quindi, questo è il trade-off secondo me. –

+3

Lo scopo del modello è separare la vista da modelli e controllori. Questa soluzione è sostanzialmente in movimento Visualizza le meta-informazioni nel controller. Il fatto che i baffi ti fanno fare queste cose sconfigge il suo scopo. I modelli non dovrebbero essere privi di logica (un'istruzione if è anch'essa logica, quindi non è comunque logica), ma i modelli dovrebbero contenere la logica di visualizzazione e nessuna logica applicativa. –

6

Usa handlebars invece. È un superset di Moustache che ti dà quel po 'più di energia di cui hai bisogno. La comunità dei baffi ha richiesto questa funzione ma il manutentore refuses to put it in.

34

Dopo aver lottato per mezza giornata con questo problema, ho finalmente trovato una soluzione facile!

Non controllare l'elenco, ma controllare se il primo elemento non è vuoto!

Template:

{{#persons.0}} 
<h2>Persons:</h2> 
<ul> 
    {{#persons}} 
    <li>{{name}}</li> 
    {{/persons}} 
</ul> 
{{/persons.0}} 
{{^persons.0}}No persons{{/persons.0}} 

dati:

{ 
    "persons":[ 
    {"name": "max"}, 
    {"name": "tom"} 
    ] 
} 

uscita:

<h2>Persons:</h2> 
<ul> 
    <li>max</li> 
    <li>tom</li> 
</ul> 

dati:

{ 
    "persons": [] 
} 

uscita:

"No Persons" 
+0

Questa risposta dovrebbe essere accettata! È una soluzione generica, solo per i baffi, che non presuppone javascript – Evgeny

+0

Non ha funzionato per me. Sto usando Mustashe.java. Questa mancanza di un condizionale al vuoto è un rompicapo per me. Torna a FreeMarker ... – dhalsim2

+0

Questo funziona. Proprio come aggiungere, per un elenco senza nome, che viene eseguito in loop utilizzando {{#.}}, Quindi è possibile utilizzare {{^.}} Nessuna persona {{/.}}. – Blizwire

39

Si potrebbe usare persons.length. Se è un valore di verità (cioè maggiore di 0), il blocco verrà reso.

{{#persons.length}} 
<h2>Persons:</h2> 
<ul> 
    {{#persons}} 
    <li>{{name}}</li> 
    {{/persons}} 
</ul> 
{{/persons.length}} 
+5

questo non funziona se si esegue il rendering lato server (fuori javascript) – iwein

+2

@iwein: la domanda * è stata * taggata 'javascript' dopo tutto, e funziona anche nel nodo :) @Qazzian: +1, una pulizia modo di evitare i baffi lambda! –

+2

@ o.v. Ho dato una risposta a questa risposta, non preoccuparti. Le informazioni aggiuntive nel commento sarebbero state comunque utili per me. – iwein

4

in JavaScript è possibile verificare con {{#names.length}}{{/names.length}} o con {{#names.0}}

Se siete al di fuori di javascript (ad esempio in pystache o Scalate), sei fuori di fortuna. L'unica soluzione è quindi introdurre un booleano separato, o annidare il tuo array in un oggetto che si evita completamente se si dispone di un array vuoto, come suggerito da maxbeatty.