Handlebars-хелпер
Handlebars-хелпер
Handlebars-хелпер представляет собой простой идентификатор, за которым следуют ноль или более параметров (через пробел). Каждый параметр представляет собой handlebars-выражение. Параметром хелпера может также являться простая строка, число или логическое значение. Хелпер производит определенные операции с параметрами и возвращает HTML код.
Handlebars-хелперам также можно передать последовательность пар ключ-значение после всех непарных параметров. Ключи должны быть простыми идентификаторами, а значения — handlebars-выражениями (т.е. значения могут быть идентификаторами, путями, или строками).
jQuery or Javascript
{{link "Подробнее..." href=poem.url class="poem"}}
Блоковые хелперы
Блоковые хелперы позволяют определять пользовательские итераторы, а также другую функциональность, с помощью которой можно вызвать переданный блок в новом контексте. Блоковый хелпер записывается следующим образом:
jQuery or Javascript
{{#helper_name}}some_block{{/helper_name}}
При регистрации хелпера параметры в Handlebars.registerHelper передаются в том порядке, в котором они были переданы хелперу пользователем. Вслед за всеми указанными пользователем параметрами следует параметр options. Он имеет следующие свойства:
options.fn — содержит функцию, которая ведет себя как обычный скомпилированный шаблон Handlebars. В качестве параметра функция принимает контекст и возвращает строку.
Пример 1. Давайте определим блоковый хелпер, который изменяет разметку обернутого в него текста:
HTML
<div class="body">
  {{#bold}}{{body}}{{/bold}}
</div>
Регистрация:
Handlebars.registerHelper('bold', function(options) { return '<div class="mybold">' + options.fn(this) + '</div>'; });
Здесь в качестве параметра функции мы передали текущий контекст (this). Давайте укажем другой контекст, передав его хелперу как параметр:
Пример 2.
HTML
<div class="entry">
{{author}}
{{#with poem}}
  <div class="title">{{title}}</div>
  <div class="author">{{../author}}</div>
  <div class="year">{{year}}</div>
{{/with}}
</div>
Выполнить этот шаблон мы могли бы со следующим JSON, имеющим вложенные в объект poem ключи title и year:
jQuery or Javascript
{
  author: "Сергей Есенин",
  poem: {
    title: "Собаке Качалова",
    year: 1925
  }
}
Регистрация:
jQuery or Javascript
Handlebars.registerHelper('with', function(context, options) {
  console.log(context);   //{title: "Собаке Качалова", year: 1925}
  return options.fn(context);
});
Мы получим HTML-код:
HTML
<div class="entry">
  Сергей Есенин
  <div class="title">Собаке Качалова</div>
  <div class="author">Сергей Есенин</div>
  <div class="year">1925</div>
</div>
Обратим внимание, что в этом примере мы использовали сегмент ../ для указания пути к свойству author, находящемуся вне контекста poem.
Пример работы:
Handlebars.registerHelper('myHelper', function(conditional, options) {
    return options.fn(conditional); // conditional - это контекст
    console.log(conditional); // conditional    - { name : "Вася"}
});
var data = {
    flowers: [
        {
            name: "Daffodil",
            product: "daffodil",
            stock: "12",
            price: 1.99,
            obj: {
                name: "Вася"
            }
        }
    ]
};
{{#each flowers}}
<div class="dcell">
    {{#myHelper obj}}
        {{name}}
    {{/myHelper}}
</div>
{{/each}}
Но если элементов несколько код работать не будет. Исправим это:
{{#each flowers}}
<div class="dcell">
    {{#if obj}} // если obj не существует будет выведено "куку"
        {{#myHelper obj}}
            {{name}}
        {{/myHelper}}
    {{else}}
    куку
    {{/if}}
    <img src="{{product}}.png"/>
    <label for="{{product}}">{{name}}:</label>
    <input name="{{product}}" data-price="{{price}}" data-stock="{{stock}}"
        value="{{#gt stock 0}}1{{else}}0{{/gt}}" required />
</div>
{{/each}}
Немного усложним ситуацию и выведем надпись лищь для тех элементов у которых есть свойство obj плюс у элемента название свойства продукт должно быть "aster"
Handlebars.registerHelper('myHelper', function(conditionalProduct, conditional, options) {
    if(conditionalProduct === "aster"){
        return options.fn(conditional);
    }
    else { //Handlebars возвращает блок, следующий за {{else}}, через функцию options.inverse:
        return options.inverse(conditional);
    }
});
<script id="flowerTmpl" type="text/x-handlebars-template">
    {{#each flowers}}
    <div class="dcell">
        {{#if  obj}}
            {{#myHelper product obj}}
                {{name}}
            {{else}}
                Здесь нет продекта с названием Aster
            {{/myHelper}}
        {{else}}
        куку
        {{/if}}
        <img src="{{product}}.png"/>
        <label for="{{product}}">{{name}}:</label>
        <input name="{{product}}" data-price="{{price}}" data-stock="{{stock}}"
            value="{{#gt stock 0}}1{{else}}0{{/gt}}" required />
    </div>
    {{/each}}
</script>
$(document).ready(function () {
    var data = {
        flowers: [
        { name: "Aster", product: "aster", stock: "10", price: 2.99,
            obj: {
                name: "Вася c Астером"
            }
        },
        { name: "Daffodil", product: "daffodil", stock: "12", price: 1.99,
            obj: {
                name: "Вася"
            }
         },
        { name: "Rose", product: "rose", stock: "2", price: 4.99 },
        { name: "Peony", product: "peony", stock: "0", price: 1.50 },
        { name: "Primula", product: "primula", stock: "1", price: 3.12 },
        { name: "Snowdrop", product: "snowdrop", stock: "15", price: 0.99 }
        ]
    };
    var tElem = $("#flowerTmpl");
    tElem.template({ flowers: data.flowers.slice(0, 3) }).appendTo("#row1");
    tElem.template({ flowers: data.flowers.slice(3) }).appendTo("#row2");
});
                
            
Комментарии к статье