Контейнеры с динамическим набором данных
В DivKit есть возможность создавать контейнеры, галереи и пейджеры с динамическим набором данных. В этом случае элементы контейнера не зашиты в верстку, а задаются при помощи вычисляемого выражения. Для этого используется свойство item_builder.
Простой пример
{
"type": "container",
"item_builder": {
"data": [
{
"text": "Item 1"
},
{
"text": "Item 2"
}
],
"data_element_name": "item",
"prototypes": [
{
"div": {
"type": "text",
"text": "@{item.getString('text')}"
}
}
]
}
}
В этом примере:
-
data
— массив данных, который будет использоваться для формирования элементов контейнера. -
data_element_name
— название переменной, содержащей данные для текущего элемента. Эта переменная доступна только внутри прототипа.Если параметр
data_element_name
не указан, переменная для доступа к данным внутри прототипа по умолчанию называетсяit
. -
prototypes
— набор прототипов, по которым формируются элементы контейнера. Прототип — это элемент верстки, который клонируется для каждого элемента данных (из массиваdata
).
В верстке из примера мы получим контейнер с двумя элементами:
-
Внутри первого элемента переменная
item
(типа dict_variable) будет содержать следующее значение:{ "text": "Item 1" }
. -
Внутри второго элемента переменная
item
будет содержать значение:{ "text": "Item 2" }
.
В итоге получится контейнер с двумя текстовыми элементами:
Item 1
Item 2
Динамический набор данных
Усложним пример: не будем зашивать данные в описание самого контейнера, а используем переменную.
{
"type": "container",
"item_builder": {
"data": "@{items}",
"data_element_name": "item",
"prototypes": [
{
"div": {
"type": "text",
"text": "@{item.getString('text')}"
}
}
]
}
}
Например, переменная items
объявлена в самой карточке и содержит те же значения, что и свойство data
в первом примере:
{
"name": "items",
"type": "array",
"value": [
{
"text": "Item 1"
},
{
"text": "Item 2"
}
]
}
При таком подходе можно динамически изменять значения переменной items
, чтобы менять содержимое контейнера. Для работы с переменными-массивами используйте действия:
Неоднородные данные
В контейнере могут содержаться элементы с разной версткой. Например, изображения и текстовые блоки. Это также можно реализовать при помощи прототипов:
{
"type": "container",
"item_builder": {
"data": [
{
"type": "text",
"text": "Item 1"
},
{
"type": "text",
"text": "Item 2"
},
{
"type": "image",
"url": "https://image.url"
}
],
"data_element_name": "item",
"prototypes": [
{
"selector": "@{item.getString('type') == 'text'}",
"div": {
"type": "text",
"text": "@{item.getString('text')}"
}
},
{
"selector": "@{item.getString('type') == 'image'}",
"div": {
"type": "image",
"image_url": "@{item.getUrl('url')}"
}
}
]
}
}
В свойстве prototypes
заданы два прототипа. Для выбора соответствующего элементу данных прототипа используется свойство selector
. В selector
можно прописать выражение, которое возвращает булево значение. Оно означает, подходит ли прототип для текущего элемента данных. Если условию удовлетворяют несколько прототипов, то используется первый.
Использование переменных в прототипах
Внутри каждого прототипа доступны:
- Текущий элемент данных через переменную, указанную в
data_element_name
(илиit
, если не указано) - Индекс текущего элемента через переменную
index
Эти переменные автоматически доступны в области видимости прототипа и могут использоваться в выражениях. Например, можно использовать @{item.getString('name')}
для доступа к полю из текущего элемента данных или @{index}
для получения позиции текущего элемента в массиве.
Узнать больше
Следите за новостями DivKit в Telegram-канале: http://t.me/divkit_news.
Также вы можете обсуждать интересующие вас темы в сообществе пользователей DivKit в Telegram: https://t.me/divkit_community_ru.