Две недели назад я рассказал об основных возможностях плагина jQuery Templates и обещал на этом не останавливаться. Обещания надо выполнять, поэтому сегодня я расскажу о дополнительных функциях, не вошедших в основной код плагина.
Дополнительные функции плагина включают:
Код дополнительных функций вынесен в файл jquery.tmplPlus.js, поэтому для их использования вы должны добавить ссылку на этот файл:
Для вызова всех команд используется метод jQuery.tmplCmd().
Этот метод имеет три формы вызова:
Параметр command используется для указания имени команды (update, remove, replace или find).
Параметр tmlItem используется для передачи ссылки на экземпляр шаблона, с которым будет работать команда. Соответственно, параметр tmplItems используется для передачи массива ссылок на экземпляры шаблонов.
Параметр data может быть ссылкой на элемент данных или массивом таких ссылок и используется для фильтрации массива tmplItems. Если указан этот параметр, в операции будут участвовать не все экземпляры шаблонов, а только те, которые связаны с указанными в параметре data элементами данных:
Какие из этих трех форм вызова применимы для каждой команды, я укажу в описании этих команд.
Команда replace, пожалуй, самая интересная из всех, она меняет порядок отрендеренных шаблонов в структуре документа в соответствии с порядком, заданным ее аргументами, причем без повторного рендеринга шаблонов.
Эта команда допускает три формы вызова, но практическое применение имеет только одна из них:
После вызова replace отрендеренные шаблоны будут переставлены в порядке, в котором в массиве data следуют ссылки на элементы данных. Идеальное решение для сортировки!
Давайте теперь посмотрим, как это работает. Данные, с которыми я буду работать в этом и в других примерах из этого раздела, находятся в массиве dataItems (полный код примера – в файле Samples.htm):
Для показа этих данных я использую следующий шаблон:
После рендеринга я сохраняю ссылки на все экземпляры шаблона в массиве tmplItems:
Обработчики событий я прикрепляю к картинкам, помеченным классами sort-asc и sort-desc в заголовке таблицы. Дополнительный атрибут x-field-name содержит имя поля, по которому будет проводиться сортировка:
Код для сортировки по возрастанию показан ниже:
Здесь я сначала получаю имя поля, по которому производится сортировка:
Затем сортирую массив с элементами данных:
И, наконец, вызываю команду replace, чтобы отобразить в документе измененные данные:
Команда replace возвращает массив ссылок на экземпляры шаблона, расположенные в том же порядке, что и отрендеренные шаблоны в документе, поэтому результат выполнения replace я сохраняю в tmplItems.
Код для сортировки по убыванию выглядит аналогично:
Как это работает, показано на видео ниже:
Команда update инициирует повторный рендеринг шаблонов. Фактически, это эквивалент метода update() экземпляра шаблона с дополнительными опциями. Самое ее логичное применение – обновить документ после изменения данных.
Эта команда допускает три формы вызова, и, в отличие от команды replace, все эти формы имеют практическое применение:
Давайте посмотрим, как она работает на примере редактора таблицы (полный код примера – в файле Samples.htm). Код для редактирования элемента показан ниже:
Здесь я сначала получаю ссылку на экземпляр шаблона и ссылку на элемент данных:
Затем вызываю диалоговое окно, которому передаю ссылку на элемент данных и callback-функцию, которая будет вызвана, если пользователь нажал OK, и данные были изменены:
А в callback-функции я вызываю команду update, указав ей ссылку на экземпляр шаблона, что вызывает его повторный рендеринг:
Как это работает, показано на видео ниже:
Команда remove, как несложно догадаться, удаляет отрендеренные шаблоны из структуры документа. Так же как и команда update, она имеет три формы вызова:
Особенностью этой команды являет то, что она не только удаляет отрендеренные шаблоны из структуры документа, но еще и удаляет из массива tmplItems ссылки на соответствующие экземпляры шаблонов!
Это, на мой взгляд, достаточно необычный подход – с одной стороны, он несколько сокращает усилия, необходимые для поддержания массива tmplItems в консистентном состоянии, а с другой – может создать неприятную ситуацию. Пожалуй, я бы предпочел, чтобы эта команда не имела побочных эффектов.
Код для удаления элемента таблицы показан ниже:
Здесь я сначала получаю ссылку на экземпляр шаблона и ссылку на элемент данных:
А после получения подтверждения от пользователя сначала удаляю соответствующий элемент из массива dataItems:
А затем удаляю соответствующий отрендеренный шаблон из структуры документа и одновременно удаляю ссылку на экземпляр шаблона из массива tmplItems:
Код функции updateDebugInfo() показан ниже:
Эта функция как раз предназначена для демонстрации побочного эффекта команды remove.
Как это работает, показано на видео ниже:
Команда find предназначена для поиска экземпляров шаблона, связанных с определенными данными. Вместе с командами update и remove она может использоваться для «точечного» обновления документа, когда повторный рендеринг всех шаблонов занимает слишком много времени.
Эта команда допускает только одну форму вызова:
Результат выполнения этой команды – массив ссылок на экземпляры шаблонов, связанных с данными, переданными через аргумент data.
Пример использования команды find приведен ниже (полный код примера – в файле Samples.htm):
В этом примере я случайным образом выбираю элемент данных:
Затем с помощью команды find нахожу экземпляр шаблона, с которым связан этот элемент данных:
И, наконец, подсвечиваю соответствующую строку таблицы:
В реальном приложении обновленные данные могут быть получены, например, с помощью AJAX-запроса.
Как это работает, показано на видео ниже:
Событие rendered определено для экземпляра шаблона и вызывается после того, как отрендеренный шаблон помещается в структуру документа.
Для задания обработчика события используется параметр options вызова .tmpl():
Самый очевидный сценарий, где может потребоваться это событие – отладка. В приведенном выше примере каждый раз при рендеринге шаблона в отладочную консоль выводится сообщение, с помощью которого легко убедиться, что команда replace действительно не производит повторный рендеринг, а команда update из приведенного выше примера обновляет только одну строку таблицы.
Как это работает, показано на видео ниже:
Полный код примеров, использованных в статье, вы можете загрузить по этой ссылке.
Напоминаю так же, что загрузить jQuery Templates можно с web-сайта ASP.NET CDN или напрямую из репозитария GitHub:
Документация по jQuery Templates доступна на сайте документации jQuery.
Дополнительные функции плагина включают:
- Набор команд, существенно упрощающих изменение отрендеренных шаблонов при изменении связанных с ними данных;
- Событие rendered, которое вызывается после того, как отрендеренный шаблон добавляется в структуру документа.
Код дополнительных функций вынесен в файл jquery.tmplPlus.js, поэтому для их использования вы должны добавить ссылку на этот файл:
<script src="Scripts/jquery-1.5.js" type="text/javascript"></script>
<script src="Scripts/jquery.tmpl.js" type="text/javascript"></script>
<script src="Scripts/jquery.tmplPlus.js" type="text/javascript"></script>
Команды для изменения отрендеренных шаблонов
Вызов команд
Для вызова всех команд используется метод jQuery.tmplCmd().
Этот метод имеет три формы вызова:
- jQuery.tmplCmd(command, tmplItem)
- jQuery.tmplCmd(command, tmplItems)
- jQuery.tmplCmd(command, data, tmplItems)
Параметр command используется для указания имени команды (update, remove, replace или find).
Параметр tmlItem используется для передачи ссылки на экземпляр шаблона, с которым будет работать команда. Соответственно, параметр tmplItems используется для передачи массива ссылок на экземпляры шаблонов.
Параметр data может быть ссылкой на элемент данных или массивом таких ссылок и используется для фильтрации массива tmplItems. Если указан этот параметр, в операции будут участвовать не все экземпляры шаблонов, а только те, которые связаны с указанными в параметре data элементами данных:
Какие из этих трех форм вызова применимы для каждой команды, я укажу в описании этих команд.
Команда replace
Команда replace, пожалуй, самая интересная из всех, она меняет порядок отрендеренных шаблонов в структуре документа в соответствии с порядком, заданным ее аргументами, причем без повторного рендеринга шаблонов.
Эта команда допускает три формы вызова, но практическое применение имеет только одна из них:
- jQuery.tmplCmd('replace', data, tmplItems)
После вызова replace отрендеренные шаблоны будут переставлены в порядке, в котором в массиве data следуют ссылки на элементы данных. Идеальное решение для сортировки!
Давайте теперь посмотрим, как это работает. Данные, с которыми я буду работать в этом и в других примерах из этого раздела, находятся в массиве dataItems (полный код примера – в файле Samples.htm):
var dataItems = [
{ firstName: 'Брюс', lastName: 'Уиллис' },
{ firstName: 'Билли Боб', lastName: 'Торнтон' },
...
];
Для показа этих данных я использую следующий шаблон:
<script id="item_tmpl" type="text/x-jquery-tmpl">
<tr class="item">
<td>${firstName}</td>
<td>${lastName}</td>
<td>
<img src="Images/item-edit.png" class="item-edit" title="Edit" />
<img src="Images/item-delete.png" class="item-delete" title="Delete" >
</td>
</tr>
</script>
После рендеринга я сохраняю ссылки на все экземпляры шаблона в массиве tmplItems:
$('#item_tmpl').tmpl(dataItems, options).appendTo('#items_bag');
tmplItems = $('#items_bag .item').map(function () {
return $.tmplItem(this);
}).get();
Обработчики событий я прикрепляю к картинкам, помеченным классами sort-asc и sort-desc в заголовке таблицы. Дополнительный атрибут x-field-name содержит имя поля, по которому будет проводиться сортировка:
<table id="items_bag">
<tr>
<th>First Name
<img src="Images/sort-asc.png" class="sort-asc" x-field-name="firstName" alt="" />
<img src="Images/sort-desc.png" class="sort-desc" x-field-name="firstName" alt="" />
</th>
<th>Last Name
<img src="Images/sort-asc.png" class="sort-asc" x-field-name="lastName" alt="" />
<img src="Images/sort-desc.png" class="sort-desc" x-field-name="lastName" alt="" />
</th>
<th></th>
</tr>
</table>
Код для сортировки по возрастанию показан ниже:
$('#items_bag').delegate('.sort-asc', 'click', function () {
var fieldName = $(this).attr('x-field-name');
dataItems.sort(function (a, b) {
return compareStrings(a[fieldName], b[fieldName]);
});
tmplItems = $.tmplCmd('replace', dataItems, tmplItems);
});
Здесь я сначала получаю имя поля, по которому производится сортировка:
var fieldName = $(this).attr('x-field-name');
Затем сортирую массив с элементами данных:
dataItems.sort(function (a, b) {
return compareStrings(a[fieldName], b[fieldName]);
});
И, наконец, вызываю команду replace, чтобы отобразить в документе измененные данные:
tmplItems = $.tmplCmd('replace', dataItems, tmplItems);
Команда replace возвращает массив ссылок на экземпляры шаблона, расположенные в том же порядке, что и отрендеренные шаблоны в документе, поэтому результат выполнения replace я сохраняю в tmplItems.
Код для сортировки по убыванию выглядит аналогично:
$('#items_bag').delegate('.sort-desc', 'click', function () {
var fieldName = $(this).attr('x-field-name');
dataItems.sort(function (a, b) {
return compareStrings(a[fieldName], b[fieldName]);
}).reverse();
tmplItems = $.tmplCmd('replace', dataItems, tmplItems);
});
Как это работает, показано на видео ниже:
Команда update
Команда update инициирует повторный рендеринг шаблонов. Фактически, это эквивалент метода update() экземпляра шаблона с дополнительными опциями. Самое ее логичное применение – обновить документ после изменения данных.
Эта команда допускает три формы вызова, и, в отличие от команды replace, все эти формы имеют практическое применение:
- jQuery.tmplCmd('update', tmplItem)
- jQuery.tmplCmd('update', tmplItems)
- jQuery.tmplCmd('update', data, tmplItems)
Давайте посмотрим, как она работает на примере редактора таблицы (полный код примера – в файле Samples.htm). Код для редактирования элемента показан ниже:
$('#items_bag').delegate('.item-edit', 'click', function () {
var tmplItem = $.tmplItem(this);
var dataItem = tmplItem.data;
editDialog.show(dataItem, function () {
$.tmplCmd('update', tmplItem);
});
});
Здесь я сначала получаю ссылку на экземпляр шаблона и ссылку на элемент данных:
var tmplItem = $.tmplItem(this);
var dataItem = tmplItem.data;
Затем вызываю диалоговое окно, которому передаю ссылку на элемент данных и callback-функцию, которая будет вызвана, если пользователь нажал OK, и данные были изменены:
editDialog.show(dataItem, function () {
$.tmplCmd('update', tmplItem);
});
А в callback-функции я вызываю команду update, указав ей ссылку на экземпляр шаблона, что вызывает его повторный рендеринг:
$.tmplCmd('update', tmplItem);
Как это работает, показано на видео ниже:
Команда remove
Команда remove, как несложно догадаться, удаляет отрендеренные шаблоны из структуры документа. Так же как и команда update, она имеет три формы вызова:
- jQuery.tmplCmd('remove', tmplItem)
- jQuery.tmplCmd('remove', tmplItems)
- jQuery.tmplCmd('remove', data, tmplItems)
Особенностью этой команды являет то, что она не только удаляет отрендеренные шаблоны из структуры документа, но еще и удаляет из массива tmplItems ссылки на соответствующие экземпляры шаблонов!
Это, на мой взгляд, достаточно необычный подход – с одной стороны, он несколько сокращает усилия, необходимые для поддержания массива tmplItems в консистентном состоянии, а с другой – может создать неприятную ситуацию. Пожалуй, я бы предпочел, чтобы эта команда не имела побочных эффектов.
Код для удаления элемента таблицы показан ниже:
$('#items_bag').delegate('.item-delete', 'click', function () {
var tmplItem = $.tmplItem(this);
var dataItem = tmplItem.data;
if (confirm('Do you really want to delete "' + dataItem.firstName + ' ' + dataItem.lastName + '"?')) {
dataItems.splice(jQuery.inArray(dataItem, dataItems), 1);
$.tmplCmd('remove', dataItem, tmplItems);
updateDebugInfo();
}
});
Здесь я сначала получаю ссылку на экземпляр шаблона и ссылку на элемент данных:
var tmplItem = $.tmplItem(this);
var dataItem = tmplItem.data;
А после получения подтверждения от пользователя сначала удаляю соответствующий элемент из массива dataItems:
dataItems.splice(jQuery.inArray(dataItem, dataItems), 1);
А затем удаляю соответствующий отрендеренный шаблон из структуры документа и одновременно удаляю ссылку на экземпляр шаблона из массива tmplItems:
$.tmplCmd('remove', dataItem, tmplItems);
Код функции updateDebugInfo() показан ниже:
function updateDebugInfo() {
$('#data_items_length').text(dataItems.length);
$('#tmpl_items_length').text(tmplItems.length);
}
Эта функция как раз предназначена для демонстрации побочного эффекта команды remove.
Как это работает, показано на видео ниже:
Команда find
Команда find предназначена для поиска экземпляров шаблона, связанных с определенными данными. Вместе с командами update и remove она может использоваться для «точечного» обновления документа, когда повторный рендеринг всех шаблонов занимает слишком много времени.
Эта команда допускает только одну форму вызова:
- jQuery.tmplCmd('find', data, tmplItems)
Результат выполнения этой команды – массив ссылок на экземпляры шаблонов, связанных с данными, переданными через аргумент data.
Пример использования команды find приведен ниже (полный код примера – в файле Samples.htm):
$('#item_rnd').click(function () {
var dataItem = dataItems[Math.round(Math.random() * (dataItems.length - 1))];
var tmplItem = $.tmplCmd('find', dataItem, tmplItems)[0];
$(tmplItem.nodes).css('background-color', '#ff0000');
$(tmplItem.nodes).animate({ 'background-color': '#ffffff' }, 1500);
});
В этом примере я случайным образом выбираю элемент данных:
var dataItem = dataItems[Math.round(Math.random() * (dataItems.length - 1))];
Затем с помощью команды find нахожу экземпляр шаблона, с которым связан этот элемент данных:
var tmplItem = $.tmplCmd('find', dataItem, tmplItems)[0];
И, наконец, подсвечиваю соответствующую строку таблицы:
$(tmplItem.nodes).css('background-color', '#ff0000');
$(tmplItem.nodes).animate({ 'background-color': '#ffffff' }, 1500);
В реальном приложении обновленные данные могут быть получены, например, с помощью AJAX-запроса.
Как это работает, показано на видео ниже:
Событие rendered
Событие rendered определено для экземпляра шаблона и вызывается после того, как отрендеренный шаблон помещается в структуру документа.
Для задания обработчика события используется параметр options вызова .tmpl():
var options = {
rendered: function (tmplItem) {
if (window.console) {
console.log("rendered: %s %s", tmplItem.data.firstName, tmplItem.data.lastName);
}
}
};
$('#item_tmpl').tmpl(dataItems, options).appendTo('#items_bag');
Самый очевидный сценарий, где может потребоваться это событие – отладка. В приведенном выше примере каждый раз при рендеринге шаблона в отладочную консоль выводится сообщение, с помощью которого легко убедиться, что команда replace действительно не производит повторный рендеринг, а команда update из приведенного выше примера обновляет только одну строку таблицы.
Как это работает, показано на видео ниже:
Заключение
Полный код примеров, использованных в статье, вы можете загрузить по этой ссылке.
Напоминаю так же, что загрузить jQuery Templates можно с web-сайта ASP.NET CDN или напрямую из репозитария GitHub:
Документация по jQuery Templates доступна на сайте документации jQuery.