Intermediate

Темплейты для данных

В этой статье мы поговорим о том, в каком виде показать данные внутри компонента, после их загрузки.

После загрузки данных в компонент, они хранятся в объекте data и компонент ищёт необходимое значение для отрисовки. Так что же такое объект значения для каждого элемента данных?

Значение элемента данных

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

Опять же, у разных компонентов разные возможности и требования:

  • Компоненты с элементами с одним значением: list и его вариации (grouplist, unitlist и x-list), dataview и tree. Каждый из их элементов содержит одно значение.
  • Компоненты с элементами с несколькими значениями: datatable и treetable. У элементов столько значений, сколько столбцов у компонента.
  • Chart требует пару значений - по значению на ось.

Как указать значение элементу:

  • JSON свойство/XML значение
//JSON
[ {id:1, value:"3", title:"" }, {id:2, value:"2", title:""} ]
 
//XML
<data><item value='3' other:""/><item value='2' other:""/></data>

Related sample:  Tree: JSON Dataset

Этот вариант подходит для элементов с одним значением. Если значений несколько, по умочланию они не будут отображаться. Чтобы показать остальные, необходимо определить темплейт.

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

Вы можете задать темплейт для любого компонента.

Через темплейты вы можете показывать одно или несколько значений:

webix.ui({
    view: "list",
    template: "#title#"
}); // этот список покажет названия ('titles')
 
webix.ui({
    view: "list",
    template: "#value#.#title#"
}); // этот список покажет 'values' и 'titles'

Related sample:  List

view: "datatable",
columns: [
    { id: "id", header: "...", width: 50}, // первый столбец показывает 'ID'
    { id: "title" }, // 2ой - названия элементов 'titles'
    { id: "value" }  // 3й - значения элементов 'values'
]

ID столбцов выполняют главную задачу темплейтов - содержат значение, которое нужно показать. Чтобы добавить какие-либо слова или форматирование значениям, вы можете задать темплейт для столбца.

{ id: "title", template: "The title is <b>#title#</b>!" }

Темплейт для CSV и JSArray

У данных типа CSV и JSArray нет ни тэгов, ни свойств.

// CSV 
'3,4 \n 2,6 \n 5, 9'
 
// JSarray
[
    [3, 4],[2, 6],[5, 9]
]

Элементы определяются по их позиции в строке CSV или JSArray - data0, data1, data3.

// темплейт для списка
template:"#data0#.#data1#" 
 
// столбцы datatable 
columns: [
    { id: "data0" },
    { id: "data1" }
];

Related sample:  Loading from an Inline Data Source

Только JSON и XML данные можно показывать без обращения к темплейту, т.к. только они могут напрямую задвать значения. Более того, это можно применить только к компоненту, у элементов которого одно значение.

Особенности Chart

Chart требует пару значений - по значению на ось.

  • Значение оси Y указывается в свойстве value, которое можно добавить в yAxis.
  • Значение оси X указывается в через темплейт внутри свойства xAxis.
webix.ui({
   view:"chart",
   value:"#data0#", // в случае CSV и JSArray
   xAxis:{
       template:"#data1#"
   },
   yAxis:{
       template:function(obj){
            return (obj%20?"":obj);
       }
   }
});

В случае темплейта-функции (описан ниже), значение доступно через obj вместо стандартного obj.value (например, obj.title, obj.data0).

Related sample:  Chart: CSV Dataset

Содержимое темплейта

Весь темплейт берётся в кавычки и включает:

  • JSON ключи / XML тэги из набора данных, с хэш-знаками (#) по обеим сторонам;
  • HTML тэги и CSS селекторы (необязательно; добавляют стилизацию);
  • обычный текст.

Пример темплейта

template: "<span style='classname'>#title#</span>. Shot in #year#. Ranked #rank#."

Title, year и rank обозначают повторяющиеся значения из данных. Все названию будут стилизованы с помощью CSS класса. 'Shot in' и 'Ranked' - обычный текст.

Дополнительно, вы можете определить темплейт для данных, скопированных в буфер обмена. Если же не определять такой темплейт, данные будут оформлены согласно вышеупомянутому темплейту.

templateCopy: "#rank#.#title#"

В этом случае, только значения rank и title будут скопированы.

У GroupList есть свой шаблон темплейта. Читайте соответствующую статью.

Необработанный элемент данных выглядит так:

//JSON
{ title: "My film", year: 1994, rank: 7 }
 
//XML
<item>
    <title>My film</title>
    <year>1994</year>
    <rank>7</rank>
</item>

Внутри компонента у него следующий вид: My film. Shot in 1998. Ranked 7.

Не путайте свойство template с компонентом template.

Типы темплейтов

Существует пять способов определения темплейтов:

  • как HTML строку с объектами JavaScript
  • через создание именованных темплейтов
  • через получение их из HTML контейнера
  • через внешний файл
  • как функция, которая возвращает строку

Темплейты включены в компоненты Webix, а также в некоторые их свойства, которые принимают объекты.

HTML внутри JavaScript

JSON данные в dataview

var big_film_set = [
    { id: 1, title: "The Shawshank Redemption",
      year: 1994, votes: "67,879",
      rating: "9.2", rank: 1
    },
    { ...}
];
 
webix.ui({       
  view: "dataview",
  template: "<div class='rank'>#rank#.</div><div class='title'>#title#</div>"
});

Related sample:  Template as a String

Именованные темплейты

Темплейты можно добавить в параметр type. Свойство применяется к каждому элементу.

  1. Прежде всего создайте тип внутри конструктора webix.type. Он создаётся для указанного компонента:
webix.type(webix.ui.dataview, {
    name: "typeA",
    template: "<div class=''>#rank#.</div>"+
            "<div class='title'>#title#</div>"+
            "<div class='year'>#year# year</div>"
});
  1. После этого укажите имя типа как значение свойства type:
webix.ui({       
    view: "dataview",
    type: "typeA"  // имя объекта webix.type 
});

Related sample:  Named Templates

В статье о типах вы найдёте более подробную информацию.

HTML контейнер с темплейтом

Вы можете определить темплейт внутри html-контейнера и обращаться по нему через ID:

<textarea id="template_container" rows="5" cols="60" style="margin-left:20px">
   <div class='overall'>
        <div class='rank'>#rank#.</div>
        <div class='title'>#title#</div>
        <div class='year'>#year#</div>
   </div>
</textarea>
 
<script>
webix.ui({       
    view: "dataview",
    // берём textarea по id и достаём его содержимое
    template: "html->template_container"
});
<script>

Related sample:  Pure HTML Template

Внушние HTML темплейты

Вы можете определять темплейты во внешних файлах. Параметр template будет ссылкой к этому файлу, с префиксом http->:

webix.ui({
    view:"dataview",
    template:"http->template.html",
    data:big_film_set
});

Содержимое файла (HTML темплейт из примера выше):

<div class="overall">
    <div class="rank">#rank#.</div>
    <div class="title">#title#</div>
    <div class="year">#year# year</div>
</div>

Обратите внимание что такие HTTP запросы не кэшируются. Если вы используете такой темплейт несколько раз, то лучшим решением будет использование AJAX и хранение темплейта в переменной:

var objectDetailTemplate = webix.ajax().sync().get('template.html').responseText;

Related sample:  Pure HTML Template: Referring to External HTML

Темплейт-функция

Темплейт может быть функцией, которая возвращает строку.

-интерполяция не работает для этого случая; вам необходим оинтерполировать переменные вручную.

// ...
template: function (obj) {
    return "<div class='overall'><div class='rank'>" + obj.rank + ".</div>" +
      "<div class='title'>" + obj.title + "</div>" +
      "<div class='year'>" + obj.year + " year</div> </div>";
}

Related sample:  Template as a Function

  • Если значение задано JSON/XML тэгом value, вам необходимо обращатсья к нему как obj.value.
  • Если значение задано темплейтом, обращайтесь к нему как obj.title, obj.rank, obj.data (CSV, JSArray), и т.д.

Параметры темплейта-функции

Темплейт-функция принимает следующие параметры:

  • obj - каждый элемент данных
  • common - общие элементы, заданные в type

Темплейты-функции у DataTable и TreeTable имеют дополнительные параметры.

Безопасные темплейты XSS

По умолчанию, плейсхолдеры #...# замещаются данными без какой-либо обработки. Если у вас есть HTML данные в объекте данных, они тоже попадают в темплейт. В большинстве случаем это преимущество, однако иногда бывает необходимо вывести данные текстом, а не HTML:

  • когда в текстовых данных есть специальные HTML символы (<, >, и &);
  • когда вы не уверены, в безопасности ли ваши данные (например, когда они введены пользователем).

В этих случаях вы можете добавить восклицательный знак ! перед открывающейся #:

{
  template: "My #data#" // выведет данные как HTML  
},
{
  template: "My #!data#" // выведет данные текстом 
},
Наверх