среда, 17 ноября 2010 г.

jQuery Templates plugin

4 октября 2010 года была опубликована запись в официальном блоге jQuery об анонсе трёх плагинов jQuery, созданных при поддержке команды Microsoft. Эти плагины - плагин шаблонов (the jQuery Templates plugin), плагин привязки данных (the jQuery Data Link plugin) и плагин глобализации (the jQuery Globalization plugin) - получили статус “Официальные плагины проекта jQuery” (officially supported plugins of the jQuery project).

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

Следует отметить, что команда Microsoft использовала свои немалые наработки в этих направлениях, как и команда проекта jQuery, и при хорошо сложившемся взаимодействии получились, на мой взгляд, отличные инструменты для разработчиков. В подтверждение моего мнения могу добавить, что разработчики jQuery анонсировали включение плагинов шаблонов и привязки данных в ядро библиотеки jQuery уже версии 1.5, а плагина глобализации - в соответствующую версию jQuery UI. Плагины пока ещё не получили статус релиза, но уже активно ведется написание документации на сайте http://api.jquery.com. К слову, команда Microsoft последовала традициям разработки jQuery и разместила материалы по разработке плагинов на github.com, где доступны описание и исходники плагинов.

jQuery Templates plugin

Начнём с простенького примера:

<script id="movieTemplate" type="text/x-jquery-tmpl">
  <li><b>${Name}</b> (${ReleaseYear})</li>
</script>

<script type="text/javascript">
var movies = [
  { Name: "The Red Violin", ReleaseYear: "1998" },
  { Name: "Eyes Wide Shut", ReleaseYear: "1999" },
  { Name: "The Inheritance", ReleaseYear: "1976" }
];

$( "#movieTemplate" ).tmpl( movies )
    .appendTo( "#movieList" );
</script>

<ul id="movieList"></ul>

Итак, в примере разработчик страницы описал шаблон для вывода объектов в виде разметки (первый элемент script), потом получил откуда-то массив объектов movies и вызвал инструкцию сгенерировать нужную разметку по шаблону, взяв данные из предоставленного массива объектов, а результат добавить в конец списка #movieList.
В результате работы плагина мы получим такую разметку:

<ul id="movieList">
  <li><b>The Red Violin</b> (1998)</li>
  <li><b>Eyes Wide Shut</b> (1999)</li>
  <li><b>The Inheritance</b> (1976)</li>
</ul>

А теперь по сути вопроса.
Что делает плагин?
Плагин получает на вход строку шаблона и множество объектов (или один объект), которые нужно вывести в строку (или разметку) с форматированием.
Где это применяется?
В основном этот плагин полезен при динамическом выводе объектов JS на страницу, объекты могут быть получены самыми разными способами, например, при разчётах или по результатам каких-то действий пользователя и, конечно самый часто приводимый пример, в виде JSON в ответе сервера на AJAX запрос.

Методы плагина

.tmpl( [ data ], [ options ] )
Получает содержимое первого выбранного элемента и использует его в качестве шаблона для форматированного вывода указанных данных.
data - данные для вывода в шаблон (объект или массив объектов).
options - опционально, определённое пользователем расширение в виде пар ключ-значение для объекта вывода в шаблон.
jQuery.tmpl(template, [ data ], [ options ])
Использует указанный шаблон для форматированного вывода указанных данных.
template - шаблон для форматирования данных, может быть одного из следующих типов: строка с разметкой, HTML-элемент (в том числе и в jQuery-обёртке), строка, соответствующая имени ранее скомпилированного шаблона.
data, options - имеют то же значение, что и выше
.tmplItem()
Возвращает для первого выбранного элемента структуру (объект) с результатами работы шаблонизатора. Возвращаемый методом объект обеспечивает доступ к:
  • HTML-частям, из которых состоит шаблон
  • ассоциированной единице переданных данных
  • родительскому шаблону, если текущий шаблон является вложенным
  • текущему шаблону, использованному для вывода
  • определённому пользователем расширению (полям и методам), переданным в параметр options метода tmpl()
Этот метод используется, напрмер, когда после проведенного форматирования данных требуется узнать, а какие же данные были использованы при формировании некоторого куска разметки, или для обновления куска разметки с использованием новых данных.
jQuery.tmplItem( element )
Аналогичен методу .tmplItem, только структура с результатами работы шаблонизатора ищется для элемента element (HTML-элемент, в том числе и в jQuery-обёртке).
.template( [ name ] )
Метод делает из содержимого первого выбранного элемента скомпилированную версию шаблона форматирования.
name - необязательно имя шаблона, если имя указано, то потом можно использовать его для обращения к этому шаблону в методе jQuery.tmpl(name, data, options)
jQuery.template( [ name, ] template )
Метод аналогичен описанному выше, только здесь шаблон передаётся в качестве параметра template - это может быть строка, строка с разметкой, HTML-элемент (в том числе и в jQuery-обёртке).

Синтаксис шаблона

Я вкратце приведу описание нескольких самых основных элементов шаблона, остальное надеюсь более подробно описать в следующей статье (если будет положительный отклик на эту статью)
${fieldNameOrExpression} и {{= fieldNameOrExpression}}
Позволяет вставить в шаблон значение поля (свойства) объекта данных, может быть также использовано для вставки результата метода или js-выражения. Напрмер, "${Name}" - вставит в шаблон значение поля obj.Name, а при том, что Languages - это поле объекта, которому присвоен массив, "${Languages.length}" - вставит в шаблон длину этого массива, и наконец, если у объекта есть метод getLanguages с двумя параметрами, то "${getLanguages(Languages, ' - ')}" - вставит в шаблон результат работы этого метода.
{{html fieldNameOrExpression}}
Элемент шаблона ${field} (или {{= field}}) вставляет в результат значение указанного поля в виде текста, т.е. если в строке будут HTML-теги, то они будут закодированы, а не преобразованы в разметку. Если вам требуется вставить данные в шаблон именно в виде HTML-разметки, то надо использовать синтаксис {{html <что нужно вставить>}}.
Для начала работы с плагином уже достаточно рассказано, могу лишь добавить, что синтаксис шаблонов позволяет вставлять вложенные шаблоны, условные инструкции, обращаться к некоторым объектам JS и jQuery и ещё кое-что... Остальное - материал будущей статьи.

Источники

Статья написана по материалам, найденным во всемирной паутине. В основном это перевод официальной документации. Оригиналы можно посмотреть по следующим ссылкам:

Примеры

Пример 1: Динамическое переключение применяемого шаблона

<!DOCTYPE html>
<html>
<head>
  <style>
    table { cursor:pointer; border-collapse:collapse; border:2px solid blue; width:300px; margin:8px; }
    table tr { border:1px solid blue; color:blue; background-color:#f8f8f8; } table td { padding:3px; } table tr:hover { color:red; }
    .movieDetail { background-color:yellow; } .movieDetail.row1 { border-bottom:none; } .movieDetail.row2 { border-top:none; }
  </style>
  <script src="http://code.jquery.com/jquery-latest.min.js"></script>
  <script src="http://nje.github.com/jquery-tmpl/jquery.tmpl.js"></script>
</head>
<body>

<script id="summaryTemplate" type="text/x-jquery-tmpl">
  <tr class='movieSummary'><td colspan='2'>${Name}</td></tr>
</script>

<script id="detailTemplate" type="text/x-jquery-tmpl">
  <tr class='movieDetail row1'><td colspan='2'>${Name}</td></tr><tr class='movieDetail row2'><td>${ReleaseYear}</td><td>Director: ${Director}</td></tr>
</script>

Click for details:
<table><tbody id="movieList"></tbody></table>

<script type="text/javascript">
var movies = [
  { Name: "The Red Violin", ReleaseYear: "1998", Director: "François Girard" },
  { Name: "Eyes Wide Shut", ReleaseYear: "1999", Director: "Stanley Kubrick" },
  { Name: "The Inheritance", ReleaseYear: "1976", Director: "Mauro Bolognini" }
];
var selectedItem = null;

/* Render the summaryTemplate with the "movies" data */
$( "#summaryTemplate" ).tmpl( movies ).appendTo( "#movieList" );

/* Add onclick handlers for movie template items
using the summary or details template */
$("#movieList")
  .delegate( ".movieSummary", "click", function () {
    if (selectedItem) {
      // Set the template on the previously selected item
      // back to the summary template
      selectedItem.tmpl = $( "#summaryTemplate" ).template();
      selectedItem.update();
    }
    /* Get the data structure for the template item
       which this clicked element belongs to, and make
       it the selected item */
    selectedItem = $.tmplItem(this);

    /* Set the template on this item to the detail template */
    selectedItem.tmpl = $( "#detailTemplate" ).template();
    selectedItem.update();
  })
  .delegate( ".movieDetail", "click", function () {
    /* Set the template on this item to the summary template */
    selectedItem.tmpl = $( "#summaryTemplate" ).template();
    selectedItem.update();
    selectedItem = null;
  });
</script>

</body>
</html>

Довольно сложный и объемный, в нём используются сразу несколько методов плагина, взят с этой страницы.

Пример 2: Вставка данных с разметкой в шаблон

<!DOCTYPE html>
<html>
<head>
  <style>
    .role {font-weight:bold;font-style: italic;} #movieContainer {padding-left: 8px;}
  </style>
  <script src="http://code.jquery.com/jquery-latest.min.js"></script>
  <script src="http://nje.github.com/jquery-tmpl/jquery.tmpl.js"></script>
</head>
<body>

<script id="movieTemplate" type="text/x-jquery-tmpl">
  <h4>${Name}</h4>
  <p>{{html Synopsis}}</p>
</script>

<div id="movieContainer"></div>

<script>
/* The Synopsis data field contains HTML markup. */
var movie = {
  Name: "Meet Joe Black",
  Synopsis: "The <span class='role'>grim reaper</span> (<a href='http://www.netflix.com/RoleDisplay/Brad_Pitt/73919'>Brad Pitt</a>) visits <span class='role'>Bill Parrish</span> (<a href='http://www.netflix.com/RoleDisplay/Anthony_Hopkins/43014'>Anthony Hopkins</a>)..."
};

/* Render the template with the movie data.
   The template uses the {{html}} template tag
   to  insert the Synopsis HTML markup data. */
$( "#movieTemplate" ).tmpl( movie )
  .appendTo( "#movieContainer" );
</script>

</body>
</html>

В этом примере в шаблон добавляются как простые строковые значения полей, так и значения с разметкой, взято вот с этой страницы.

P.S.

Это дубль моей статьи на сайте про jQuery Официальные плагины jQuery: Templates plugin