Handlebars.js Else If

241

Estoy usando Handlebars.js para la representación de la vista lateral del cliente. Si Else funciona muy bien pero he encontrado un condicional de 3 vías que requiere ELSE IF:

Esto no 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}}

¿Cómo hago ELSE IF con el manillar?

reach4thelasers
fuente
Esté atento a las actualizaciones del manillar, parece que se implementará pronto: github.com/wycats/handlebars.js/pull/892
Jacob van Lingen

Respuestas:

376

Los manillares admiten {{else if}}bloques a partir de 3.0.0.

Manillares v3.0.0 o 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 de Handlebars v3.0.0, sin embargo, tendrá que definir un ayudante que maneje la lógica de ramificación o anidar ifmanualmente:

{{#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
fuente
66
es el punto de no tener un elsif (o si no) en el manillar que está poniendo demasiada lógica en su plantilla. En otras palabras, ¿necesita dividirlo en plantillas más pequeñas?
Kazim Zaidi
1
@KazimZaidi, ¿qué pasa si tiene un solo dato con más de tres estados que requiere un formato diferente en cada caso? Es posible que pueda forzar un estilo CSS en los datos en sí, pero luego está presionando las preocupaciones a nivel de vista en sus datos. Puedo imaginar casos sensibles para una construcción if / elseif / endif (o incluso un interruptor / coincidencia).
Drew Noakes
1
Al mirar esto nuevamente, siento que esto se puede hacer a través de enlaces de atributos.
Kazim Zaidi
1
Creo que el método preferido es pasar banderas booleanas y condicionalizarlas. Depende de usted establecer los indicadores correctamente de modo que solo una condición se evalúe como verdadera. No es necesarioelse if
chovy
Recomiendo que haga esto con una función auxiliar para separar su lógica de negocios de la presentación.
Max Hodges
76

Usualmente uso este formulario:

{{#if FriendStatus.IsFriend}}
  ...
{{else}} {{#if FriendStatus.FriendRequested}}
  ...
{{else}}
  ...
{{/if}}{{/if}}
drinor
fuente
Buen consejo, gracias. ¿Sería esto reactivo por defecto?
kylemclaren
2
Se ve bonito con solo 1 más si, pero cuanto más tenga, más larga {{/if}}{{/if}}{{/if}}{{/if}}{{/if}}
será la
1
No, no es "más limpio", es más feo.
gen b.
37

Los manillares ahora son compatibles a {{else if}}partir de 3.0.0. Por lo tanto, su código ahora debería funcionar.

Puede ver un ejemplo en "condicionales" (ligeramente revisado aquí con un agregado {{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

No hacer
fuente
44
¡Esta debería ser la nueva respuesta!
Saad Malik
no funciona para mí (error de sintaxis en la plantilla). Meteor 1.2.0.2
dragonmnl
@dragonmnl ¿Qué versión de Handlebars está usando Meteor 1.2.0.2? Asegúrate de estar usando 3.0.
Don O
Estoy usando la versión predeterminada. ¿Cómo verifico la versión del manillar?
dragonmnl
@dragonmnl Parece que Meteor usa su propio lenguaje de plantillas llamado Spacebars . Si ese es el caso, entonces no estoy seguro de que sea compatible con la {{else if}}sintaxis.
Don O
37

El espíritu del manillar es que no tiene lógica. A veces esto nos hace sentir como si estuviéramos luchando con él, y a veces terminamos con una lógica if / else fea y anidada. Usted podría escribir un ayudante; muchas personas aumentan el manillar con un operador condicional "mejor" o creen que debería ser parte del núcleo . Sin embargo, creo que en lugar de esto,

{{#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}}

es posible que desee organizar las cosas en su modelo para que pueda tener esto,

{{#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}}

Solo asegúrese de que solo una de estas banderas sea cierta. Lo más probable es que si está usando esto if/elsif/elseen su punto de vista, probablemente también lo esté usando en otro lugar, por lo que estas variables podrían no ser superfluas.

Mantenlo delgado.

Ziggy
fuente
1
No estoy seguro de qué tan buena práctica es, pero esto se me ocurrió hoy manejando 3 estados de vista diferentes y terminé usando una solución basada en esto (su lógica si no es necesaria ya que todos están comparando un valor) stackoverflow.com/questions/15008564/… Entonces, en lugar de #if _is_friend, puede usar una cadena con un asistente muy simple (en su respuesta); #if friend_type "is_friend" y #if friend_type "is_not_friend_yet"
Dylan Reich
Esta respuesta es lo que consideraría la mejor solución antes del manillar 3.0, creo que HTML adicional es mejor en lugar de intentar meter la lógica en el árbol DOM.
David O'Regan
7

Escribí este simple ayudante:

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);
  }
});

Es algo así como el patrón de la Cadena de Responsabilidad en Manillares

Ejemplo:

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

No es otra cosa, pero en algunos casos puede ayudarte)

Kirill Ermolov
fuente
1

Ayudantes incorporados

#if

Puede usar el asistente if para representar condicionalmente un bloque. Si su argumento devuelve falso, indefinido, nulo, "", 0 o [], los manillares no mostrarán el bloque.

modelo

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

Cuando pasa la siguiente entrada a la plantilla anterior

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

Hola, solo tengo una edición de nombre de clase MENOR, y hasta ahora así es como se divulgó. Creo que necesito pasar parámetros de pila múltiple al asistente

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
fuente