Статьи

Шаблонирование в Javascript

В последние несколько недель я работал с шаблонами на стороне клиента. Поскольку большинство веб-разработчиков, казалось, не знакомы с этой концепцией, и им было немного не по себе, оборачиваясь вокруг нее, вот краткое объяснение всей идеи.

Код для этого поста можно скачать здесь или посмотреть здесь .

Форматирование вывода с помощью JavaScript

В большинстве (всех?) Веб-приложений вам в какой-то момент придется отображать некоторые отформатированные данные. Это может быть так же просто, как персонализированное приветствие, или так же сложно, как динамический график с наворотами. Не имеет значения — по сути, вам все равно придется преобразовать ваш объект данных в какой-то вид HTML.

Достойный времени — и неправильный — способ сделать это — объединить строки, используя оператор +. Вы знаете, как

$("#greeting").html("Hello " + user.name+"!");

Это выглядит достаточно безобидно, но может быстро стать сложным — предположим, что вам нужно включить туда больше переменных или просто сделать его локализуемым — размещение слов не соответствует одному и тому же порядку в каждом языке, поэтому вам потребуется другой шаблон на язык. По моему опыту, большинство переводчиков не являются техническими специалистами, поэтому переводить выражения на самом деле не очень хорошая идея. Конкатенированную строку также сложнее для чтения, поэтому, если вам нужно внести какие-либо изменения или получить очень длинную цепочку текста, вас ждет головная боль. Добавить в условия, коллекции и другие забавные вещи, и это действительно больно.

Как не сойти с ума

Большинство фреймворков javascript предоставляют какой-то шаблонизатор, встроенный или как плагин. В этом примере я собираюсь использовать Усы , потому что он поддерживает некоторые элегантные функции, которые другие не делают. Концепции, однако, остаются почти такими же, за исключением синтаксиса.

Определение шаблона

Наиболее распространенным способом определения шаблона является использование тега script. Задавая ему тип «текст / шаблон» (некоторые движки используют разные типы, но это не должно иметь большого значения), вы говорите браузеру, что он не должен рассматривать содержимое тега script как javascript, так что он не будет пытаться запустить его и пойти бум. Фактически, он будет спокойно игнорировать элемент, позволяя вам определить свой шаблон внутри, например:

<script type="text/template" id="article">
    <article data-key="{{id}}" data-permalink="{{permalink}}">
        <h1>{{title}}</h1>
        <h2>by {{author.firstName}} {{author.lastName}}</h2>
        <section class="summary">{{summary}}</section>
        <section class="content">
            {{content}}
        </section>
    </article>
</script>

как вы можете видеть, это выглядит как обычный, обычный html — эквивалент как конкатенация:

"<article data-key=\"" +id + "\" data-permalink=\"" + permalink + "\"><h1>" + title + "</h1><h2>by " + author.firstName + " " + author.lastName + "</h2><section>" + summary + "</section><section>" + content + "</section></article>"

Если вы хотите использовать шаблон, вы можете получить содержимое элемента script и использовать его. Усы позволяют вам использовать это сразу; другие системы шаблонов могут потребовать, чтобы вы сначала создали экземпляр шаблона, поэтому проверьте документацию выбранной вами системы.

Чтобы получить исходный текст шаблона, вы можете использовать любой метод доступа к содержимому элемента, будь то функция jQuery .html () или стандартное поле js innerHTML . Затем вы можете передать это вместе со своими данными в ваш движок шаблонов. В нашем случае мы будем использовать простой объект:

var data = {
    id: 0,
    permalink:"http://xyz.com/0",
    title:"Ender's Game",
    author:{ firstName:"Orson Scott", lastName:"Card"},
    summary: "Some random text here",
    content: "A bit more information here."
}

Итак, введя это в шаблон:

var formattedData = Mustache.to_html($("#article").html(), data);

Мы получаем красивую строку, которую затем можем поместить в любом месте нашего документа:

<article data-key="0" data-permalink="http://xyz.com/0">
    <h1>Ender's Game</h1>
    <h2>by Orson Scott Card</h2>
    <section class="summary">Some random text here</section>
    <section class="content">
        A bit more information here.
    </section>
</article>

Здесь вы можете видеть, что все заполнители были заменены значениями из объекта данных. Усы достаточно умны, чтобы использовать вложенные объекты, как в случае поля автора; вы можете получить доступ к свойствам внутри дочернего объекта, как если бы вы использовали обычный js.

Еще одна удобная функция

Помимо обработки вложенных объектов, усы могут также обрабатывать вложенные коллекции. Это, очевидно, удобно, поскольку приложения почти всегда имеют дело с коллекциями вещей. Нам просто нужно сообщить Mustache, что метка-заполнитель предназначена для коллекции, добавив к ней префикс # и определив для нее подшаблон, например:

<aside class="related">
    <h2>Related articles</h2>
    {{#related}}
    <article data-key="{{id}}" data-permalink="{{permalink}}">
        <h1>{{title}}</h1>
        <h2>by {{author.firstName}} {{author.lastName}}</h2>
    </article>
    {{/related}}
</aside>

Используя данные:

var data = {
...
    related:[
        { id: 1, permalink: "http://xyz.com/1", title: "Speaker for the dead", author:{ firstName:"Orson Scott", lastName:"Card"}},
        { id: 2, permalink: "http://xyz.com/2", title: "The Fires of Heaven", author:{ firstName:"Robert", lastName:"Jordan"}}
    ]
}

Мы получаем

<aside class="related">
    <h2>Related articles</h2>
    <article data-permalink="http://xyz.com/1" data-key="1">
        <h1>Speaker for the dead</h1>
        <h2>by Orson Scott Card</h2>
    </article>
    <article data-permalink="http://xyz.com/2" data-key="2">
        <h1>The Fires of Heaven</h1>
        <h2>by Robert Jordan</h2>
    </article>
</aside>

Не все движки шаблонов предоставляют такую ​​поддержку, но, как правило, легко обойти ее, создав шаблоны, повторяя коллекцию и добавляя заполнитель.

Некоторые ошибки

Синтаксис шаблона может не учитываться языком серверной части, который вы используете в некоторых случаях — например, JSP не нравится синтаксис шаблона Prototype. Вы можете настроить или настроить свой движок шаблонов, чтобы обойти это при необходимости.

Следует помнить одну вещь: разницу между источником шаблона, экземпляром шаблона (если он есть) и шаблонными данными — я видел, как несколько человек пытались использовать сам шаблон в качестве вывода, что не сработает. Итак: Источник шаблона — это разметка с заполнителями, которые мы определили ранее. Экземпляр шаблона — это то, что возьмет наши данные и наш источник шаблона и соединит их вместе, и, наконец, шаблонные данные — это конечный продукт, который мы хотим использовать, с установленными значениями. Пример, который звучит так, будто я вытащил его из своей задницы (потому что это именно то, что произошло), но каким-то образом помог некоторым людям вспомнить, заключается в следующем: вывод — это cookie; шаблон является формирователем cookie, а источником шаблона является дизайн формирователя. Помните, какой вы хотите съесть.

Закрытие

Если вы еще не использовали шаблоны, попробуйте их сами. С ними гораздо проще справиться, чем с конкатенацией.

«А если ты не слушаешь, то, черт возьми, с тобой!»

-Конан-варвар