Ext.XTemplate
Фреймворк ExtJS обладает таким мощным средством, как шаблоны. Шаблоны позволяют выполнять отдельные куски кода JavScript и встраивать разметку, и тем самым определять содержимое элементов и компонентов.
Шаблоны определяются с помощью класса Ext.XTemplate
. Теперь посмотрим, как можно использовать шаблоны. Например, определим следующий объект,
который в свою очередь представляет массив некоторых объектов javascript:
var tiobeData = [ { position: 1, title: 'C', rate: '19.224%' }, { position: 2, title: 'Java', rate: '17.455%' }, { position: 3, title: 'Objective-C', rate: '10.383%' }, { position: 4, title: 'C++', rate: '9.689%' }, { position: 5, title: 'PHP', rate: '5.732%' }];
Теперь мы можем встроить его в разметку веб-страницы, используя объект Ext.XTemplate:
Ext.onReady(function(){ var tpl = new Ext.XTemplate ('<h1>TIOBE Rate</h1>', '<table>', '<tr>', '<td>Позиция на Ноябрь 2012</td>', '<td>Язык программирования</td>', '<td>Рейтинг</td>', '</tr>', '<tpl for=".">', '<tr>', '<td>{position}</td>', '<td>{title}</td>', '<td>{rate}</td>', '</tr>', '</tpl>', '</table>'); tpl.overwrite(Ext.getBody(), tiobeData); });
И шаблон сгенерирует нам следующее наполнение веб-страницы:
В данном случае мы использовали метод overwrite
для вставки разметки на страницу. Этот метод принимает два обязательных параметра:
элемент страницы, который надо заполнить данными (в данном случае весь элемент body веб-страницы), и объект данных, из которого ведется наполнение.
Выражение или тег <tpl for=".">
вводит шаблон в разметку, объявляя цикл for. Таким образом, данный шаблон сгенерирует идентичную разметку для каждого объекта в переменной
tiobeData. Используя выражения в фигурных скобках, например, {position}
подставляется соответствующее свойство объектов в переменной tiobeData.
Ext.XTemplate поддерживает разные способы работы с массивами:
<tpl for=".">...</tpl> // цикл по массиву элементов в корневом узле, как в предыдущем случае <tpl for="data">...</tpl> // цикл по массиву в узле data <tpl for="data.sub">...</tpl> // цикл по массиву в узле data.sub <tpl for="." between=",">...</tpl> // цикл по массиву в корневом узле и вставка знака запятой между элементами из массива
Например, определим некоторый объект, который у нас будет хранить массив животных:
var allData = { animals: [ {name: 'слон', weight: 8500}, {name: 'тигр', weight: 120}, {name: 'медведь', weight: 350}] };
То мы могли бы использовать следующий шаблон:
var tpl = new Ext.XTemplate('<h1>Животные</h1>', '<ul>', '<tpl for="animals">', '<li>{name}</li>', '</tpl>', '</ul>'); tpl.overwrite(Ext.getBody(), allData);
Условные конструкции в шаблонах
С помощью XTemplate мы можем не просто подставлять нужные значения объектов, но и использовать более сложную логику. Так, мы можем использовать условные конструкции if как и в языках программирования.
Изменим код шаблона, который выводит данные о языках программирования. Например, мы изменим стиль тех четных строк - окрасим их в другой цвет, и зададим логику вывода дополнительного столбца, содержание которого будет различаться в зависимости от позиции языка программирования:
Ext.onReady(function(){ var tpl = new Ext.XTemplate('<h1>Рейтинг TIOBE</h1>', '<table>', '<tr>', '<td>Позиция на Ноябрь 2012</td>', '<td>Язык программирования</td>', '<td>Рейтинг</td>', '<td>Группа</td>', '</tr>', '<tpl for=".">', '<tr <tpl if="values.position%2 == 1">style="background-color: silver;"</tpl>>', '<td>{position}</td>', '<td>{title}</td>', '<td>{rate}</td>', '<tpl if="values.position<3">', '<td>A</td>', '<tpl elseif="values.position<5">', '<td>B</td>', '<tpl else>', '<td>C</td>', '</tpl>', '</tr>', '</tpl>', '</table>'); tpl.overwrite(Ext.getBody(), tiobeData); });
Данный код даст нам следующее содержание:
Чтобы получить текущий передаваемый объект в цикле, в Ext.XTemplate имеется свойство values
. Через это свойство затем мы можем
обратиться уже непосредственно к свойствам объекта. Так, используя выражение values.position
, мы обращаемся к свойству position
Встроенное в определение строки <tr>
выражение tpl позволяет в зависимости от значения свойства position
определить цвет данной строки.
Далее идущая конструкция позволяет в зависимости от значения свойства использовать конструкцию if...elseif..else для вывода нужных нам данных.
Кроме свойства values Ext.XTemplate имеет еще ряд полезных свойств:
parent - указывает на родителя текущего объекта. То есть в данном случае при переборе в цикле всех объектов, это свойство будет иметь в качестве значения объект, внутри которого и объявлен массив перебираемых объектов.
xindex - указывает на индекс текущего перебираемого элемента в массиве
xcount - показывает общее количество перебираемых объектов
Встраивание в шаблон кода JavaScript
Класс XTemplate позволяет нам использовать функции javascript, которые встраиваются в шаблон, для обработки данных. Так, вернемся к нашей модели с языками программирования. Допустим, мы хотим сделать так, что если входное значение равно "C", то к нему должна добавляться подстрока "(ANSI)":
var tpl = new Ext.XTemplate('<h1>TIOBE Rate</h1>', '<table>', '<tr>', '<td>Позиция на Ноябрь 2012</td>', '<td>Язык программирования</td>', '<td>Рейтинг</td>', '</tr>', '<tpl for=".">', '<tr <tpl if="values.position%2 == 1">style="background-color: silver;"</tpl>>', '<td>{position}</td>', '<td>{[this.getStringValue(values.title)]}</td>', '<td>{rate}</td>', '</tr>', '</tpl>', '</table>', { getStringValue: function(values){ if(values=="C"){return "C (ANSI)";} else {return values} } }); tpl.overwrite(Ext.getBody(), tiobeData);
Таким образом, мы можем объявить некоторую функцию форматирования значения и затем использовать эту функцию вместо свойства, а само свойство передавать в качестве параметра функции.