Handlebars.js se não

241

Estou usando o Handlebars.js para renderização de exibição do lado do cliente. Se Else funcionar bem, mas eu encontrei uma condicional de 3 vias que requer ELSE IF:

Isso não funciona:

{{#if FriendStatus.IsFriend }}
    <div class="ui-state-default ui-corner-all" title=".ui-icon-mail-closed"><span class="ui-icon ui-icon-mail-closed"></span></div>
{{else if FriendStatus.FriendRequested}}
    <div class="ui-state-default ui-corner-all" title=".ui-icon-check"><span class="ui-icon ui-icon-check"></span></div>
{{else}}
    <div class="ui-state-default ui-corner-all" title=".ui-icon-plusthick"><span class="ui-icon ui-icon-plusthick"></span></div>
{{/if}}

Como eu faço ELSE SE com guidão?

reach4thelasers
fonte
Mantenha-se atento às atualizações guiador, parece que vai ser implementado em breve: github.com/wycats/handlebars.js/pull/892
Jacob van Lingen

Respostas:

376

O guidão suporta {{else if}}blocos a partir do 3.0.0.

Guiador v3.0.0 ou superior:

{{#if FriendStatus.IsFriend}}
  <div class="ui-state-default ui-corner-all" title=".ui-icon-mail-closed"><span class="ui-icon ui-icon-mail-closed"></span></div>
{{else if FriendStatus.FriendRequested}}
  <div class="ui-state-default ui-corner-all" title=".ui-icon-check"><span class="ui-icon ui-icon-check"></span></div>
{{else}}
  <div class="ui-state-default ui-corner-all" title=".ui-icon-plusthick"><span class="ui-icon ui-icon-plusthick"></span></div>
{{/if}}

Antes do Handlebars v3.0.0, no entanto, você precisará definir um auxiliar que manipule a lógica de ramificação ou aninhar ifmanualmente as instruções:

{{#if FriendStatus.IsFriend}}
  <div class="ui-state-default ui-corner-all" title=".ui-icon-mail-closed"><span class="ui-icon ui-icon-mail-closed"></span></div>
{{else}}
  {{#if FriendStatus.FriendRequested}}
    <div class="ui-state-default ui-corner-all" title=".ui-icon-check"><span class="ui-icon ui-icon-check"></span></div>
  {{else}}
    <div class="ui-state-default ui-corner-all" title=".ui-icon-plusthick"><span class="ui-icon ui-icon-plusthick"></span></div>
  {{/if}}
{{/if}}
Carl
fonte
6
é o ponto em não ter um elsif (ou então se) no guidão que você está colocando muita lógica em seu modelo. Em outras palavras, você precisa dividi-lo em modelos menores?
Kazim Zaidi
1
@KazimZaidi, e se você tiver um único dado com mais de três estados que requer formatação diferente em cada caso? Você pode forçar um estilo CSS nos próprios dados, mas está inserindo preocupações no nível da visualização nos dados. Eu posso imaginar casos sensatos para uma construção if / elseif / endif (ou mesmo um switch / match).
de Drew Noakes
1
olhando para isso de novo, acho que isso pode ser feito por meio de ligações de atributos.
Kazim Zaidi
1
Eu acho que o método preferido é passar sinalizadores booleanos e condicioná-los. Cabe a você definir os sinalizadores corretamente, de modo que apenas uma condição seja avaliada como verdadeira. Não há necessidade deelse if
Chovy
Eu recomendo que você faça isso com uma função auxiliar para separar sua lógica de negócios da apresentação.
Max Hodges
76

Eu costumo usar este formulário:

{{#if FriendStatus.IsFriend}}
  ...
{{else}} {{#if FriendStatus.FriendRequested}}
  ...
{{else}}
  ...
{{/if}}{{/if}}
drinor
fonte
Boa dica, obrigado. Isso seria reativo por padrão?
Kylemclaren
2
Parece bonito com apenas mais 1 se, mas quanto mais você tiver, mais longa será a última lista de se - {{/if}}{{/if}}{{/if}}{{/if}}{{/if}}
jbyrd
1
Não, não é "limpo", é mais feio.
gene b.
37

O guidão agora suporta {{else if}} partir do 3.0.0. Portanto, seu código agora deve funcionar.

Você pode ver um exemplo em "condicionais" (ligeiramente revisado aqui com uma adição {{else}}:

    {{#if isActive}}
      <img src="star.gif" alt="Active">
    {{else if isInactive}}
      <img src="cry.gif" alt="Inactive">
    {{else}}
      <img src="default.gif" alt="default">
    {{/if}}

http://handlebarsjs.com/block_helpers.html

Don O
fonte
4
Essa deve ser a nova resposta!
Saad Malik
não funciona para mim (erro de sintaxe no modelo). Meteor 1.2.0.2
dragonmnl
@dragonmnl Qual versão do guidão o Meteor 1.2.0.2 está usando? Verifique se você está usando o 3.0.
Don O
Estou usando a versão padrão. Como verifico a versão do guiador?
dragonmnl
@dragonmnl Parece que o Meteor usa sua própria linguagem de modelos chamada Barra de espaço . Se for esse o caso, não tenho certeza se ele suporta a {{else if}}sintaxe.
Don O
37

O espírito do guidão é que ele é "sem lógica". Às vezes, isso nos faz sentir como se estivéssemos lutando com ela, e às vezes acabamos com uma lógica if / else aninhada feia. Você poderia escrever um ajudante; muitas pessoas aumentam o guidão com um operador condicional "melhor" ou acreditam que ele deve fazer parte do núcleo . Eu acho que, em vez disso,

{{#if FriendStatus.IsFriend}}
  <div class="ui-state-default ui-corner-all" title=".ui-icon-mail-closed"><span class="ui-icon ui-icon-mail-closed"></span></div>
{{else}}
  {{#if FriendStatus.FriendRequested}}
    <div class="ui-state-default ui-corner-all" title=".ui-icon-check"><span class="ui-icon ui-icon-check"></span></div>
  {{else}}
    <div class="ui-state-default ui-corner-all" title=".ui-icon-plusthick"><span class="ui-icon ui-icon-plusthick"></span></div>
  {{/if}}
{{/if}}

convém organizar as coisas no seu modelo para que você possa ter isso,

{{#if is_friend }}
  <div class="ui-state-default ui-corner-all" title=".ui-icon-mail-closed"><span class="ui-icon ui-icon-mail-closed"></span></div>
{{/if}}

{{#if is_not_friend_yet }}
    <div class="ui-state-default ui-corner-all" title=".ui-icon-check"><span class="ui-icon ui-icon-check"></span></div>
{{/if}}

{{#if will_never_be_my_friend }}
    <div class="ui-state-default ui-corner-all" title=".ui-icon-plusthick"><span class="ui-icon ui-icon-plusthick"></span></div>
{{/if}}

Apenas certifique-se de que apenas uma dessas bandeiras seja verdadeira. As chances são de que, se você estiver usando isso if/elsif/elsena sua visualização, provavelmente também o estiver usando em outro lugar, portanto, essas variáveis ​​podem não acabar sendo supérfluas.

Mantenha-o magro.

Ziggy
fonte
1
Não tenho certeza de como é uma boa prática, mas hoje surgiu para mim lidar com três estados de exibição diferentes e acabei usando uma solução baseada nisso (a lógica elseif deles não é necessária, pois todos estão verificando um valor) stackoverflow.com/questions/15008564/… Então, em vez de #if _is_friend, você pode usar uma string com um auxiliar muito simples (na resposta); #if friend_type "is_friend" e #if friend_type "is_not_friend_yet"
Dylan Reich
Esta resposta é a que eu consideraria a melhor solução antes do guidão 3.0, acho que o HTML extra é melhor em vez de tentar empinar a lógica na Árvore DOM.
David O'Regan
7

Eu escrevi este ajudante simples:

Handlebars.registerHelper('conditions', function (options) {
    var data = this;
    data.__check_conditions = true;
    return options.fn(this);
});


Handlebars.registerHelper('next', function(conditional, options) {
  if(conditional && this.__check_conditions) {
      this.__check_conditions = false;
      return options.fn(this);
  } else {
      return options.inverse(this);
  }
});

É algo como o padrão de cadeia de responsabilidade no guidão

Exemplo:

    {{#conditions}}
        {{#next condition1}}
            Hello 1!!!
        {{/next}}
        {{#next condition2}}
            Hello 2!!!
        {{/next}}
        {{#next condition3}}
            Hello 3!!!
        {{/next}}
        {{#next condition4}}
            Hello 4!!!
        {{/next}}
    {{/conditions}}

Não é outra coisa, mas, em alguns casos, isso pode ajudá-lo)

Kirill Ermolov
fonte
1

Ajudantes internos

#if

Você pode usar o auxiliar if para renderizar um bloco condicionalmente. Se o argumento retornar falso, indefinido, nulo, "", 0 ou [], o Handlebars não renderizará o bloco.

modelo

<div class="entry">
  {{#if author}}
    <h1>{{firstName}} {{lastName}}</h1>
  {{else}}
    <h1>Unknown Author</h1>
  {{/if}}
</div>

Quando você passa a seguinte entrada para o modelo acima

{
  author: true,
  firstName: "Yehuda",
  lastName: "Katz"
}
Abdo-Host
fonte
0

Olá, tenho apenas uma edição MENOR do nome da classe e, até agora, foi assim que a divulgamos. acho que preciso passar parâmetros de várias pilhas para o ajudante,

server.js

app.engine('handlebars', ViewEngine({
        "helpers":{
                isActive: (val, options)=>{
                    if (val === 3 || val === 0){
                        return options.fn(this)
                    }
                } 
        }
}));

header.handlebars

<ul class="navlist">
          <li   class="navitem navlink {{#isActive 0}}active{{/isActive}}"
                ><a href="#">Home</a></li>
          <li   class="navitem navlink {{#isActive 1}}active{{/isActive}}"
                ><a href="#">Trending</a></li>
          <li   class="navitem navlink {{#isActive 2}}active{{/isActive}}"
                ><a href="#">People</a></li>
          <li   class="navitem navlink {{#isActive 3}}active{{/isActive}}"
                ><a href="#">Mystery</a></li>
          <li class="navitem navbar-search">
            <input type="text" id="navbar-search-input" placeholder="Search...">
            <button type="button" id="navbar-search-button"><i class="fas fa-search"></i></button>
          </li>
        </ul>
Maddocks
fonte