В настоящее время большая часть Интернета состоит из динамических приложений, в которых данные постоянно меняются. В результате существует постоянная необходимость обновления данных, отображаемых в браузере. Вот где JavaScript-движки приходят на помощь и становятся такими полезными. Они упрощают процесс обновления представления вручную и в то же время улучшают структуру приложения, позволяя разработчикам отделить бизнес-логику от остальной части кода. Некоторые из наиболее известных шаблонизаторов JavaScript — это Mustache , Underscore , EJS и Handlebars . В этой статье мы сосредоточим наше внимание на руле , обсуждая его основные функции.
Руль: что это такое и зачем его использовать
Handlebars — это логико-шаблонный движок, который динамически генерирует вашу HTML-страницу. Это расширение усов с несколькими дополнительными функциями. Усы полностью без логики, но Handlebars добавляет минимальную логику благодаря использованию некоторых помощников (например, with
, unless
, each
и более), которые мы обсудим далее в этой статье. На самом деле, мы можем сказать, что Handlebars — это надстройка усов.
Рули могут быть загружены в браузер, как и любой другой файл JavaScript:
<script src="/path/to/handlebars.min.js"></script>
Если вы спрашиваете, почему вы должны использовать этот шаблонизатор, а не другой, вы должны взглянуть на его плюсы. Вот краткий список:
- Он поддерживает чистоту вашей HTML-страницы и отделяет шаблоны без логики от бизнес-логики в файлах JavaScript, тем самым улучшая структуру приложения (а также его удобство обслуживания и масштабируемость).
- Это упрощает задачу ручного обновления данных в представлении
- Он используется в популярных платформах и платформах, таких как Ember.js , Meteor.js , Derby.js и Ghost.
Я надеюсь, что это краткое резюме поможет вам решить, стоит ли использовать руль или нет.
Как это работает ?
Как показано на приведенной выше диаграмме, способ работы руля можно обобщить следующим образом:
- Handlebars берет шаблон с переменными и компилирует его в функцию
- Затем эта функция выполняется путем передачи объекта JSON в качестве аргумента. Этот объект JSON известен как контекст, и он содержит значения переменных, используемых в шаблоне
- При выполнении функция возвращает необходимый HTML после замены переменных шаблона на соответствующие им значения.
Чтобы понять вышеупомянутый процесс, давайте начнем с демонстрации, которая подробно объясняет все вышеупомянутые шаги.
Шаблоны
Шаблоны могут быть написаны как в файле HTML, так и отдельно. В первом случае они появляются внутри <script>
с атрибутом type="text/x-handlebars-template"
и идентификатором. Переменные записываются в двойных фигурных скобках {{}}
и называются выражениями. Вот пример:
<script id="handlebars-demo" type="text/x-handlebars-template"> <div> My name is {{name}}. I am a {{occupation}}. </div> </script>
С этой разметкой мы можем видеть, что нам нужно сделать, чтобы использовать ее. В вашем файле JavaScript нам сначала нужно извлечь шаблон из HTML-документа. В следующем примере мы будем использовать идентификатор шаблона для этой цели. После того, как шаблон был получен, мы можем скомпилировать его с помощью метода Handlebars.compile()
который возвращает функцию. Затем эта функция выполняется путем передачи контекста в качестве аргумента. Когда выполнение завершено, функция возвращает желаемый HTML со всеми переменными, замененными их соответствующими значениями. На данный момент мы можем внедрить HTML в нашу веб-страницу.
Превращение этого описания в код приводит к следующему фрагменту:
Демонстрационную версию этого кода можно найти в этой демонстрационной версии Codepen
синтаксисы
Теперь пришло время погрузиться немного глубже в руль. Мы рассмотрим несколько важных терминов и синтаксисов, которые составляют ядро руля.
Выражения
Мы уже видели выражения в приведенном выше разделе. Переменные, используемые внутри шаблонов, заключены в двойные фигурные скобки {{}}
и называются выражениями:
My name is {{name}}
HTML Escape
Handlebars могут экранировать значение, возвращаемое выражением. Например, символ <
преобразуется в <
. Если вы не хотите, чтобы Handlebars экранировали значение, вы должны заключить переменную в тройные фигурные скобки {{{variableName}}}
. Например, когда следующий шаблон:
I am learning {{language}}. It is {{{adjective}}}.
используется с переменной context
указанной ниже:
var context = { "language" : "<h3>Handlebars</h3>", "adjective": "<h3>awesome</h3>" }
результирующий HTML будет:
I am learning <h3>Handlebars</h3>. It is <h3>awesome</h3>
Демонстрацию, демонстрирующую эту функцию, можно найти в этой демонстрации Codepen.
Комментарии
Мы также можем писать комментарии в шаблонах Handlebars. Синтаксис для комментариев Handlebars: {{!TypeYourCommentHere}}
. Однако каждый комментарий, содержащий }}
или любой другой символ, имеющий особое значение в Handlebars, должен быть записан в виде {{!--TypeYourCommentHere--}}
. Комментарии на руле не видны в HTML, но если вы хотите их показать, вы можете использовать стандартный комментарий HTML: <!--comments-->
.
Если мы применим все эти концепции к используемому шаблону, мы можем придумать код, показанный ниже:
<!-- I am learning {{language}} --> I am learning {{language}}. It is {{!--adjective--}}
Если мы используем предыдущий шаблон с context
переменной, о которой сообщается ниже:
var context = { "language" : "Handlebars", "adjective": "awesome" }
вывод HTML будет:
<!-- I am learning Handlebars --> I am learning Handlebars. It is
в результате браузер не будет отображать содержимое внутри стандартного HTML-комментария. Демо этого примера можно найти здесь.
Блоки
В Handlebars блоки - это выражения, которые открываются ( {{# }}
) и закрываются ( {{/}}
). Мы подробно изучим эту тему позже, сосредоточившись на помощниках. А пока посмотрим, как пишется блок if
:
{{#if boolean}} Some Content here {{/if}}
пути
Handlebars поддерживает как обычный, так и вложенный путь, что позволяет искать свойства, вложенные в текущий контекст. Handlebars также поддерживает сегмент ../
path. Этот сегмент ссылается на родительскую область шаблона, а не на один уровень выше в контексте.
Для лучшего понимания этой темы мы воспользуемся приведенным ниже примером, в котором мы используем each
помощника (подробно обсуждается позже). Как и следовало ожидать, последний перебирает элементы массива.
В этом примере мы будем использовать следующий шаблон:
This article is available on {{website.name}}.<br/> {{#each names}} I am a {{../occupation}}. My name is {{firstName}} {{lastName}}.<br/> {{/each}}
Предоставляя эту переменную context
:
var context = { "occupation" : "developer", "website" : { "name" : "sitepoint" } "names" : [ {"firstName" : "Ritesh", "lastName" : "Kumar"}, {"firstName" : "John" , "lastName" : "Doe"} ] }
мы получим вывод, показанный ниже:
Как и другие небольшие фрагменты, которые мы создали до сих пор, этот пример доступен на Codepen
Помощники
Несмотря на то, что Handlebars - это шаблонизатор без логики, он может выполнять простую логику с помощью помощников. Помощник Handlebars - это простой идентификатор, за которым могут следовать параметры (разделенные пробелом), как показано ниже:
{{#helperName parameter1 parameter2 ...}} Content here {{/helperName}}
Каждый параметр является выражением Handlebars. Эти помощники могут быть доступны из любого контекста в шаблоне.
Термины «блок», «помощник» и «помощник блока» иногда используются взаимозаменяемо, так как большинство встроенных помощников являются блоками, хотя есть помощники функций, которые немного отличаются от помощников блоков. Мы обсудим их при освещении пользовательских помощников.
Некоторые встроенные помощники есть if
, each
, unless
и with
. Давайте узнаем больше.
each
помощник
each
помощник используется для перебора массива. Синтаксис помощника: {{#each ArrayName}} YourContent {{/each}}
. Мы можем ссылаться на отдельные элементы массива, используя ключевое слово this
внутри блока. Индекс элемента массива можно {{@index}}
с помощью {{@index}}
. Пример ниже иллюстрирует использование each
помощника.
Если мы используем следующий шаблон:
{{#each countries}} {{@index}} : {{this}}<br> {{/each}} {{#each names}} Name : {{firstName}} {{lastName}}<br> {{/each}}
в сочетании с этой переменной context
:
var context = { "countries":["Russia","India","USA"], "names" : [ {"firstName":"Ritesh","lastName":"Kumar"}, {"firstName":"John","lastName":"Doe"} ] }
тогда вывод будет:
Демонстрацию этого примера можно найти на Codepen .
if
Хелпер
Помощник if
похож на оператор if
. Если условие оценивается как истинное значение, Handlebars отрендерит блок. Мы также можем указать раздел шаблона, известный как «else section», используя {{else}}
. Вспомогательный параметр " unless
является обратным к вспомогательному. Он отображает блок, когда условие оценивается как ложное значение.
Чтобы показать, как работает помощник if
, давайте рассмотрим шаблон ниже:
{{#if countries}} The countries are present. {{else}} The countries are not present. {{/if}}
Если мы предоставим следующую context
переменную:
var context = { "countries": [] }
Мы получим результат, указанный ниже:
The countries are not present.
Это происходит потому, что пустой массив является ложным значением.
Если вы хотите поиграть с помощниками, вы можете посмотреть живую демонстрацию, которую я создал на Codepen .
Пользовательские Помощники
Вы можете создавать своих собственных помощников для выполнения сложных логик, используя систему выражений, которую предоставляет Handlebars. Есть два вида помощников: функциональные помощники и блокирующие помощники . Первое определение предназначено для одного выражения, а второе - для блочных выражений. Аргументы, предоставляемые функции обратного вызова, представляют собой параметры, записанные после имени помощника, разделенные пробелом. Помощники создаются с помощью метода Handlebars.registerHelper()
:
Handlebars.registerHelper("HelperName", function(arguments){ // This function is executed whenever this helper is used })
Пользовательский помощник функции
Синтаксис для помощника функции: {{helperName parameter1 parameter2 ...}}
. Чтобы лучше понять, как приступить к реализации, давайте создадим помощник функции с именем studyStatus
который возвращает строку, которая будет «передана», если passingYear < 2015
и «не пройдена», если passingYear >= 2015
:
Handlebars.registerHelper("studyStatus", function(passingYear) { if(passingYear < 2015) { return "passed"; } else { return "not passed"; } })
В нашем примере параметр только один. Однако, если мы хотим передать больше параметров в функцию обратного вызова помощника, мы можем записать их в шаблон после первого параметра, разделенного пробелом.
Давайте разработаем пример с этим шаблоном:
{{#each students}} {{name}} has {{studyStatus passingYear}}.<br> {{/each}}
и со следующей context
переменной:
var context = { "students":[ {"name" : "John", "passingYear" : 2013}, {"name" : "Doe" , "passingYear" : 2016} ] }
В этом случае вывод будет:
John has passed. Doe has not passed.
Демонстрация этого примера доступна здесь.
Пользовательский блок помощник
Помощники пользовательских блоков используются так же, как и помощники функций, но синтаксис немного другой. Синтаксис блок помощников:
{{#helperName parameter1 parameter2 ...}} Your content here {{/helperName}}
Когда мы регистрируем пользовательский помощник блока, Handlebars автоматически добавляет объект options
в качестве последнего параметра в функцию обратного вызова. Этот объект options
имеет метод fn()
который позволяет нам временно изменить контекст объекта для доступа к определенному свойству. Давайте изменим пример предыдущего раздела, используя вспомогательный блок с именем studyStatus
но с той же переменной context
:
Handlebars.registerHelper("studyStatus", function(data, options){ var len = data.length; var returnData=""; for(var i=0;i<len;i++){ // change the value of the passingYear to // passed/not passed based on the conditions. data[i].passingYear=(data[i].passingYear < 2015) ? "passed" : "not passed"; // here options.fn(data[i]) temporarily changes the // scope of the whole studyStatus helper // block to data[i]. So {{name}}=data[i].name // in the template. returnData = returnData + options.fn(data[i]); } return returnData; }); var context = { "students":[ {"name" : "John", "passingYear" : 2013}, {"name" : "Doe" , "passingYear" : 2016} ] }
Если этот код используется в сочетании с шаблоном, определенным ниже
{{#studyStatus students}} {{name}} has {{passingYear}} {{/studyStatus}}
мы получим следующий результат:
John has passed. Doe has not passed.
А вот и демоверсия Codepen .
Частичные шаблоны
Частицы Handlebars - это шаблоны, которые могут использоваться несколькими шаблонами. Они написаны как {{> partialName}}
. Прежде чем использовать их в HTML, нам нужно зарегистрировать частичное с помощью метода Handlebars.registerPartial()
. Следующий пример поможет вам понять, как зарегистрировать частичное имя с именем partialTemplate
:
Handlebars.registerPartial( 'partialTemplate', '{{language}} is {{adjective}}. You are reading this article on {{website}}.' ); var context={ "language" : "Handlebars", "adjective": "awesome" }
При использовании с шаблоном, определенным ниже
{{> partialTemplate website="sitepoint"}} <br> {{> partialTemplate website="www.sitepoint.com"}}
Это даст следующий результат:
Handlebars is awesome. You are reading this article on sitepoint Handlebars is awesome. You are reading this article on www.sitepoint.com
Демонстрацию этого кода можно найти в этой демонстрации Codepen .
Прекомпиляция
Как мы уже видели, первое, что делает Handlebars, это компилирует шаблон в функцию. Это одна из самых дорогих операций для клиента. Мы можем улучшить производительность приложения, если предварительно скомпилируем templateScript
а затем отправим скомпилированную версию клиенту. В этом случае единственной задачей, которую необходимо выполнить на клиенте, будет выполнение этой функции. Поскольку предварительно скомпилированный файл является скриптом, мы можем загрузить скрипт в HTML как обычный файл. Давайте посмотрим, как все это можно сделать.
Во-первых, вы должны установить Handlebars глобально, используя npm install handlebars -g
. Пожалуйста, убедитесь, что разные шаблоны написаны в отдельных файлах с разными именами и с расширениями .handlebars
(например, demo.handlebars
). В этих файлах нет необходимости использовать <script>
.
<div> My name is {{name}}. I am a {{occupation}}. </div>
Теперь храните все файлы шаблонов в одной папке с именем templates
. Вы можете использовать любое имя папки, которое пожелаете, но если вы это сделаете, пожалуйста, не забудьте соответствующим образом изменить следующую команду. Итак, откройте терминал и выполните команду:
handlebars path/to/templates -f templatesCompiled.js
Эта команда создаст файл с именем templatesCompiled.js
который содержит все скомпилированные шаблоны. Компилятор вставит шаблоны в Handlebars.templates
. Если входной файл demo.handlebars
, то он будет вставлен в Handlebars.templates.demo
Теперь мы должны включить templatesCompiled.js
в HTML-файл как обычный script
. Важно отметить, что нам не нужно загружать всю библиотеку Handlebars, так как сам компилятор больше не нужен. Вместо этого мы можем использовать меньшую сборку «runtime»:
<script src="handlebars.runtime.js"></script> <script src="path/to/templatesCompiled.js"></script>
Теперь мы можем использовать шаблон, который изначально присутствовал в demo.handlebars
, используя следующий код:
var context = { "name" : , "occupation" : "developer" } var templateScript = Handlebars.templates.demo(context); $(document.body).append(templateScript);
Окончательный результат будет следующим:
Этот метод значительно повысит производительность приложения, и время загрузки страницы также уменьшится, поскольку мы используем сборку Handlebars во время выполнения, которая легче, чем вся библиотека.
Код всей этой демонстрации предварительной компиляции доступен на GitHub .
Выводы
В этой статье мы обсудили основные понятия руля. Мы также рассмотрели его часто используемые функции и синтаксисы. Я надеюсь, вам понравился этот урок, и вы будете использовать прилагаемые демонстрации, чтобы хорошо разбираться в этой теме. Я с нетерпением жду ваших комментариев.
Если вы не хотите загружать библиотеку, но все же хотите попробовать ее, вы можете поиграть с Handlebars онлайн по адресу http://tryhandlebarsjs.com/ .