Handlebars.js иначе если

241

Я использую Handlebars.js для рендеринга со стороны клиента. Если Else работает отлично, но я столкнулся с трехсторонним условием, требующим ELSE IF:

Это не работает:

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

Как мне сделать ELSE IF с рулем?

reach4thelasers
источник
Следите за обновлениями руля, похоже, он скоро будет реализован: github.com/wycats/handlebars.js/pull/892
Джейкоб ван Линген,

Ответы:

377

Handlebars поддерживает {{else if}}блоки с 3.0.0.

Рули v3.0.0 или выше:

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

Однако до Handlebars v3.0.0 вам придется либо определить помощника, который обрабатывает логику ветвления, либо ifоператоры вложений вручную:

{{#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}}
деревенщина
источник
6
смысл в том, чтобы в руле не было elsif (или еще if), что вы вкладываете слишком много логики в свой шаблон. Другими словами, вам нужно разбить его на более мелкие шаблоны?
Казим Заиди,
1
@KazimZaidi, что если у вас есть один фрагмент данных с более чем тремя состояниями, который требует различного форматирования в каждом случае? Возможно, вам удастся навязать стиль CSS для самих данных, но затем вы добавляете в свои данные проблемы уровня просмотра. Я могу представить разумные случаи для конструкции if / elseif / endif (или даже для параметра switch / match).
Дрю Ноакс
1
Глядя на это снова, я чувствую, что это можно сделать с помощью привязок атрибутов.
Казим Заиди
1
Я думаю, что предпочтительный метод - передать логические флаги и обусловить их. Вы должны правильно установить флаги так, чтобы только одно условие оценивалось как true. Не нужноelse if
Чови
Я бы порекомендовал вам сделать это с помощью вспомогательной функции, чтобы отделить бизнес-логику от представления.
Макс Ходжес
76

Я обычно использую эту форму:

{{#if FriendStatus.IsFriend}}
  ...
{{else}} {{#if FriendStatus.FriendRequested}}
  ...
{{else}}
  ...
{{/if}}{{/if}}
drinor
источник
Хороший совет, спасибо. Будет ли это реактивным по умолчанию?
kylemclaren
2
Выглядит красиво только с 1, если, но чем больше у вас есть, тем длиннее последний список закрытия, если получает -{{/if}}{{/if}}{{/if}}{{/if}}{{/if}}
jbyrd
1
Нет, это не "чище", это страшнее.
ген б.
37

Handlebars теперь поддерживает {{else if}}начиная с 3.0.0. Поэтому ваш код теперь должен работать.

Вы можете увидеть пример в разделе «условные выражения» (слегка пересмотренный здесь с добавлением {{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

Дон О
источник
4
Это должен быть новый ответ!
Саад Малик
не работает для меня (синтаксическая ошибка в шаблоне). Метеор 1.2.0.2
dragonmnl
@dragonmnl Какую версию Handlebars использует Meteor 1.2.0.2? Убедитесь, что вы используете 3.0.
Дон О
Я использую версию по умолчанию. Как проверить версию руля?
dragonmnl
@dragonmnl Похоже, что Метеор использует свой собственный язык шаблонов, называемый пробелами . Если это так, то я не уверен, что он поддерживает {{else if}}синтаксис.
Дон О
37

Дух руля заключается в том, что он «не логичен». Иногда это заставляет нас чувствовать, что мы боремся с этим, а иногда мы получаем некрасивую вложенную логику if / else. Вы могли бы написать помощника; многие люди дополняют руль «лучшим» условным оператором или считают, что он должен быть частью ядра . Я думаю, что вместо этого

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

вы можете расположить вещи в своей модели так, чтобы вы могли иметь это,

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

Просто убедитесь, что только один из этих флагов верен. Скорее всего, если вы используете это if/elsif/elseв своем представлении, вы, вероятно, используете его и где-то еще, поэтому эти переменные могут не оказаться лишними.

Держите это постным.

Ziggy
источник
1
Я не уверен, насколько это полезно для практики, но сегодня я столкнулся с 3 различными состояниями просмотра, и я решил использовать решение, основанное на этом (их логика elseif не нужна, поскольку все они проверяют одно значение) stackoverflow.com/questions/15008564/… Таким образом, вместо #if_is_friend вы можете использовать строку с очень простым помощником (в их ответе); #if friend_type "is_friend" и #if friend_type "is_not_friend_yet"
Дилан Райх
Этот ответ - то, что я бы назвал лучшим решением до руля 3.0, я думаю, что дополнительный HTML лучше, чем попытка втиснуть логику в дерево DOM.
Дэвид О'Реган
7

Я написал этот простой помощник:

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

Это что-то вроде цепочки ответственности в руле

Пример:

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

Это не иначе, если, но в некоторых случаях это может помочь вам)

Кирилл Ермолов
источник
1

Встроенные помощники

#if

Вы можете использовать помощник if для условного рендеринга блока. Если его аргумент возвращает false, undefined, null, "", 0 или [], Handlebars не будет визуализировать блок.

шаблон

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

Когда вы передаете следующий вход в шаблон выше

{
  author: true,
  firstName: "Yehuda",
  lastName: "Katz"
}
Абдо-Host
источник
0

Здравствуйте, у меня есть только редактирование имени класса MINOR, и до сих пор это то, как я его разгласил. я думаю, что мне нужно передать в несколько параметров кучи помощнику,

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>
Мэддокс
источник