Handlebars с более сложными данными

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>


view

Плейсхолдеры для {{title}} и {{description}} это простые значения, которые мы уже видели во введении в Handlebars, но здесь также есть цикл для прохождения по элементам массива. {{#each articles}} начинает цикл по элементам массива, лежащего в ключе articles. Цикл заканчивается, когда мы достигаем инструкции {{/each}}. Внутри цикла мы можем использовать ключи объектов, которые являются элементами массива articles.

Это делает шаблон гораздо чише, чем он был раньше, когда мы использовали конкатенацию.

Author

Gabor Szabo (szabgab) Gabor Szabo