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");
});
Комментарии к статье