Handlebars с более сложными данными
В статье, где мы впервые рассмотрели Handlebars (шаблонизатор JavaScript), был работающий пример, но возможно он был недостаточно убедителен в отношении, почему использование Handlebars лучше конкатенации для создания HTML сниппетов.
Затем был еще этот пример с Ajax запросом, возвращающим JSON данные. Там мы также использовали простой JavaScript, но там было уже совсем неприятно. Давайте теперь посмотрим, как мы можем делать те же самые вещи, используя Handlebars.
В предыдущем примере мы получили JSON-ответ со следующим содержимым:
examples/js/data.json
{ "title" : "Code Maven", "description" : "Coding is fun!", "articles" : [ { "title" : "Handling user events in JavaScript", "url" : "http://code-maven.com/handling-events-in-javascript" }, { "title" : "On-load counter with JavaScript and local storage", "url" : "http://code-maven.com/on-load-counter-with-javascript-and-local-storage" } ] }
Мы использовали этот код:
examples/js/ajax.js
function ajax_get(url, callback) { var xmlhttp = new XMLHttpRequest(); xmlhttp.onreadystatechange = function() { if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { console.log('responseText:' + xmlhttp.responseText); try { var data = JSON.parse(xmlhttp.responseText); } catch(err) { console.log(err.message + " in " + xmlhttp.responseText); return; } callback(data); } }; xmlhttp.open("GET", url, true); xmlhttp.send(); } ajax_get('/try/examples/js/data.json', function(data) { document.getElementById("title").innerHTML = data["title"]; var html = "<h2>" + data["title"] + "</h2>"; html += "<h3>" + data["description"] + "</h3>"; html += "<ul>"; for (var i=0; i < data["articles"].length; i++) { html += '<li><a href="' + data["articles"][i]["url"] + '">' + data["articles"][i]["title"] + "</a></li>"; } html += "</ul>"; document.getElementById("text").innerHTML = html; });
Используя Handlebars
Функция ajax_get осталась такой же. Она была рассмотрена в статье про Ajax запрос.
Изменения в строках 23-25, где вместо конкатенации HTML по фрагментам, мы получаем шаблон из элемента с id text-template, компилируем исходный код шаблона в функцию template, а затем просто передаем в нее данные, которые мы получили из Ajax запроса. Намного чище, чем раньше, когда мы должны были думать об использовании одинарных кавычек снаружи так, чтобы они не пересекались с двойными кавычками, которые мы хотели использовать для HTML атрибутов.
examples/js/ajax_handlebars.js
function ajax_get(url, callback) { xmlhttp = new XMLHttpRequest(); xmlhttp.onreadystatechange = function() { if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { console.log('responseText:' + xmlhttp.responseText); try { var data = JSON.parse(xmlhttp.responseText); } catch(err) { console.log(err.message + " in " + xmlhttp.responseText); return; } callback(data); } }; xmlhttp.open("GET", url, true); xmlhttp.send(); } ajax_get('/try/examples/js/data.json', function(data) { document.getElementById("title").innerHTML = data["title"]; var source = document.getElementById('text-template').innerHTML; var template = Handlebars.compile(source); var html = template(data); document.getElementById("text").innerHTML = html; });
Сам шаблон находится в HTML файле в теге script.
examples/js/ajax_handlebars.html
<script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/3.0.1/handlebars.min.js"></script> <script id="text-template" type="text/x-handlebars-template"> <h2>{{title}}</h2> <h3>{{description}}</h3> <ul> {{#each articles}} <li><a href="{{url}}">{{title}}</a></li> {{/each}} </ul> </script> <h1 id="title"></h1> <hr> <div id="text"></div> <script src="ajax_handlebars.js"></script>Try!
Плейсхолдеры для {{title}} и {{description}} это простые значения, которые мы уже видели во введении в Handlebars, но здесь также есть цикл для прохождения по элементам массива. {{#each articles}} начинает цикл по элементам массива, лежащего в ключе articles. Цикл заканчивается, когда мы достигаем инструкции {{/each}}. Внутри цикла мы можем использовать ключи объектов, которые являются элементами массива articles.
Это делает шаблон гораздо чише, чем он был раньше, когда мы использовали конкатенацию.

Published on 2015-05-03