Come realizzo un if / else in moustache.js?


258

Sembra piuttosto strano che non riesca a capire come farlo nei baffi. È supportato?

Questo è il mio triste tentativo di provare:

    {{#author}}
      {{#avatar}}
        <img src="{{avatar}}"/>
      {{/avatar}}
      {{#!avatar}}
        <img src="/images/default_avatar.png" height="75" width="75" />
      {{/avatar}}
    {{/author}}

Questo ovviamente non è giusto, ma la documentazione non menziona nulla di simile. La parola "altro" non è nemmeno menzionata :(

Inoltre, perché i baffi sono progettati in questo modo? Questo genere di cose è considerato negativo? Sta cercando di costringermi a impostare il valore predefinito nel modello stesso? E i casi in cui ciò non è possibile?


1
"perché i baffi sono progettati in questo modo?" Non sono troppo sicuro, ma penso che l'idea sia che un linguaggio di modello dovrebbe essere proprio questo: un linguaggio per scrivere modelli, cioè cose che sembrano l'output che producono, solo con buchi dove vanno i bit delle variabili. Inserire la logica nel linguaggio dei template rende i template più complicati e quando hai già un linguaggio di programmazione per gestire i bit logici, perché preoccuparsi?
Paul D. Waite,

4
@ PaulD.Waite "Senza logica" significa davvero "codice non arbitrario", credo. Mettere la vera logica di visualizzazione nel codice è altrettanto grave che inserire la logica di non visualizzazione in un modello. Moustache cerca di fornire una logica minima nuda per farlo.
jpmc26,

2
Oppure usa il manubrio anziché i baffi. Essere in grado di scrivere, ad esempio, {{#each items}}{{#unless @first}}Output comma before 2nd, 3rd, 4th...{{/unless}}{{/each}}è più leggibile, molto più pulito ed è ancora presentazione. "Logic-less" è una linea guida, non deve essere una camicia di forza.
skierpage,

Forse non è un motore di template abbastanza versatile quando un OP dice "questo è il mio triste tentativo [...] questo ovviamente non è giusto" ... e quindi la risposta accettata è una copia-incolla di quel codice :). Nessun giudizio su OP o risposta; proprio sumustache
dwanderson il

Risposte:


498

Ecco come fare se / else in Moustache (perfettamente supportato):

{{#repo}}
  <b>{{name}}</b>
{{/repo}}
{{^repo}}
  No repos :(
{{/repo}}

O nel tuo caso:

{{#author}}
  {{#avatar}}
    <img src="{{avatar}}"/>
  {{/avatar}}
  {{^avatar}}
    <img src="/images/default_avatar.png" height="75" width="75" />
  {{/avatar}}
{{/author}}

Cerca le sezioni invertite nei documenti: https://github.com/janl/mustache.js


89
I documenti sui baffi sono esilaranti. "Lo chiamiamo" senza logica "perché non ci sono istruzioni if, clausole else o loop." Yeeeeaaaaaa ....
scatola il

6
@boxed, tecnicamente hai ragione, la sezione invertita è un'istruzione logica, in quanto controlla il valore del tag. Ma penso che la sfumatura qui sia che entrambe le affermazioni debbano essere valutate esplicitamente, piuttosto che un singolo if / else. In sostanza, i baffi forza la struttura if (condition){ //do something}seguita da a if (!condition){//do something else}. Inoltre, la quantità di logica che si può eseguire in logica estremamente ridotta rispetto a un linguaggio basato sulla logica. L'esistenza o la non esistenza sono gli unici controlli, ovvero non è possibile verificare se il valore di un tag è uguale a 5 e quindi rientrare nel codice di quel tag.
MandM,

22
@MandM sì ... quindi ha una logica ma non può fare nulla di utile: P
scatola il

Ti impedisce solo di fare confusione con la logica se altro. Avere un sacco di nidi se / else all'interno di un altro if / else è un segno di errore di progettazione
Tebe

@boxed puoi farlo per loop con moustache.js (almeno ngPer-ish loop)
aloisdg si trasferisce su codidact.com il

54

Questo è qualcosa che risolvi nel "controller", che è il punto del modello logico.

// some function that retreived data through ajax
function( view ){

   if ( !view.avatar ) {
      // DEFAULTS can be a global settings object you define elsewhere
      // so that you don't have to maintain these values all over the place
      // in your code.
      view.avatar = DEFAULTS.AVATAR;
   }

   // do template stuff here

}

In realtà, questo è MOLTO meglio del mantenimento dell'URL delle immagini o di altri media che potrebbero o non potrebbero cambiare nei modelli, ma a cui ci vuole un po 'per abituarsi. Il punto è disimparare la visione del tunnel dei modelli, un URL img url è destinato ad essere utilizzato in altri modelli, hai intenzione di mantenere quell'URL sui modelli X o un singolo oggetto impostazioni DEFAULTS? ;)

Un'altra opzione è quella di fare quanto segue:

// augment view
view.hasAvatar = !!view.avatar;
view.noAvatar = !view.avatar;

E nel modello:

{{#hasAvatar}}
    SHOW AVATAR
{{/hasAvatar}}
{{#noAvatar}}
    SHOW DEFAULT
{{/noAvatar}}

Ma questo va contro l'intero significato del modello senza logica. Se è quello che vuoi fare, vuoi un modello logico e non dovresti usare Moustache, anche se dai a te stesso una buona possibilità di apprendere questo concetto;)


Grazie. È un'ottima risposta! In realtà mi ha aiutato anche con altri aspetti strutturali su "quando fare cose" nella struttura del codice javascript.
egervari,

{{/ # hasAvatar}} e {{/ # noAvatar}} dovrebbero essere {{/ hasAvatar}} e {{/ noAvatar}} in questa risposta.
Mulhoon,

14

La tua dichiarazione else dovrebbe assomigliare a questa (nota il ^):

{{^avatar}}
 ...
{{/avatar}}

Nei baffi questo si chiama 'Sezioni invertite'.


7
nota che non hai bisogno sia di # che di ^, è solo ^ per il caso "non"
zappan,

Questo non funziona nell'ultima versione. Zappan ha ragione, hai solo bisogno del ^
simonmorley del

0

Puoi definire un aiutante nella vista. Tuttavia, la logica condizionale è piuttosto limitata. Moxy-Stencil ( https://github.com/dcmox/moxyscript-stencil ) sembra risolverlo con aiutanti "parametrizzati", ad esempio:

{{isActive param}}

e nella vista:

view.isActive = function (path: string) {return path === this.path? "class = 'active'": ''}


0

Nota, è possibile utilizzare {{.}}per eseguire il rendering dell'elemento di contesto corrente.

{{#avatar}}{{.}}{{/avatar}}

{{^avatar}}missing{{/avatar}}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.