Como realizo um if / else no mustache.js?

258

Parece bastante estranho que eu não consiga entender como fazer isso no bigode. É suportado?

Esta é minha triste tentativa de tentar:

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

Obviamente, isso não está certo, mas a documentação não menciona nada disso. A palavra "else" nem é mencionada :(

Além disso, por que o bigode é projetado dessa maneira? Esse tipo de coisa é considerado ruim? Ele está tentando me forçar a definir o valor padrão no próprio modelo? E os casos em que isso não é possível?

egervari
fonte
1
"por que o bigode é projetado dessa maneira?" Não tenho muita certeza, mas acho que a idéia é que uma linguagem de modelagem deva ser exatamente isso: uma linguagem para escrever modelos, ou seja, coisas que se pareçam com a saída que produzem, apenas com furos para onde os bits variáveis ​​vão. Colocar a lógica na linguagem de modelos torna os modelos mais complicados e, quando você já possui uma linguagem de programação para lidar com os bits lógicos, por que se preocupar?
Paul D. Waite
4
@ PaulD.Waite "Sem lógica" realmente significa "código não arbitrário", eu acho. É tão ruim colocar a lógica de visualização verdadeira no código quanto colocar a lógica de não visualização em um modelo. O bigode tenta fornecer uma lógica mínima para fazer isso.
precisa saber é o seguinte
2
Ou use guidão em vez de bigode. Ser capaz de escrever, por exemplo, {{#each items}}{{#unless @first}}Output comma before 2nd, 3rd, 4th...{{/unless}}{{/each}}é mais legível, muito mais limpo e ainda é uma apresentação. "Sem lógica" é uma diretriz, não precisa ser uma camisa de força.
Skierpage
Talvez não seja um mecanismo de modelagem versátil o suficiente quando um OP diz "esta é minha triste [...] tentativa, obviamente isso não está certo" ... e então a resposta aceita é uma cópia e colar desse código :). Nenhum julgamento sobre OP ou resposta; apenas onmustache
dwanderson

Respostas:

498

É assim que você faz se / else no Bigode (perfeitamente suportado):

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

Ou no seu caso:

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

Procure seções invertidas nos documentos: https://github.com/janl/mustache.js

Eneko Alonso
fonte
89
Os documentos do bigode são hilários. "Chamamos isso de" menos lógica "porque não há instruções if, cláusulas else ou loops". Yeeeeaaaaaa ....
caixa de
6
@boxed, tecnicamente você está certo, a seção invertida é uma declaração lógica, pois verifica o valor da tag. Mas acho que a nuance aqui é que ambas as declarações precisam ser avaliadas explicitamente, em vez de uma única if / else. Basicamente, o bigode força a estrutura if (condition){ //do something}seguida por a if (!condition){//do something else}. Além disso, a quantidade de lógica que se pode executar na lógica é extremamente reduzida em comparação com uma linguagem baseada em lógica. Existência ou inexistência são as únicas verificações, ou seja, você não pode verificar se o valor de uma tag é igual a 5 e depois cai no código dessa tag.
181 MandM
22
@ Mandand sim ... por isso tem lógica, mas simplesmente não pode fazer nada de útil: P
encaixotado em
Isso evita que você se engane com a lógica. Ter um monte de aninhados if / else dentro de outro if / else é um sinal de mal projetado
Tebe
@boxed você pode fazer por loop com moustache.js (pelo menos ciclo ngFor-ish)
aloisdg se mudar para codidact.com
54

Isso é algo que você resolve no "controlador", que é o ponto da modelagem sem lógica.

// 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

}

Na verdade, é MUITO melhor do que manter os URLs da imagem ou outras mídias que podem ou não mudar nos seus modelos, mas é necessário algum tempo para se acostumar. O objetivo é desaprender a visão do túnel do modelo; um URL de img de avatar deve ser usado em outros modelos. Você manterá esse URL nos modelos X ou em um único objeto de configurações DEFAULTS? ;)

Outra opção é fazer o seguinte:

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

E no modelo:

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

Mas isso vai contra todo o significado da modelagem sem lógica. Se é isso que você quer fazer, deseja modelagem lógica e não deve usar o Bigode, embora tenha a chance de aprender esse conceito;)

BGerrissen
fonte
Obrigado. Essa é uma ótima resposta! Na verdade, ele também me ajudou com outros aspectos estruturais sobre "quando fazer coisas" na estrutura do código javascript.
egervari 17/05
{{/ # hasAvatar}} e {{/ # noAvatar}} devem ser {{/ hasAvatar}} e {{/ noAvatar}} nesta resposta.
Mulhoon 22/08/12
14

Sua declaração else deve ter esta aparência (observe o ^):

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

No bigode, isso é chamado de "seções invertidas".

anonimato
fonte
7
Note que você não precisa de tanto # e ^, é apenas ^ para o caso de 'não'
zappan
Isso não funciona na versão mais recente. O Zappan está correto, você só precisa do ^
simonmorley
0

Você pode definir um auxiliar na exibição. No entanto, a lógica condicional é um pouco limitada. O Moxy-Stencil ( https://github.com/dcmox/moxyscript-stencil ) parece abordar isso com ajudantes "parametrizados", por exemplo:

{{isActive param}}

e na vista:

view.isActive = função (caminho: string) {caminho de retorno === this.path? "class = 'active'": ''}

Daniel
fonte
0

Observe que você pode usar {{.}}para renderizar o item de contexto atual.

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

{{^avatar}}missing{{/avatar}}
Hafthor
fonte