Контейнеры с динамическим набором данных

В 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, чтобы менять содержимое контейнера. Для работы с переменными-массивами используйте действия: array_insert_value, array_remove_value, array_set_value.

Неоднородные данные

В контейнере могут содержаться элементы с разной вёрсткой. Например, изображения и текстовые блоки. Это также можно реализовать при помощи прототипов:

{
  "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 можно прописать выражение, возвращающее булево значение, которое означает, подходит ли прототип для текущего элемента данных. Если несколько прототипов удовлетворяют условию, то используется первый.

Узнать больше

Следите за новостями DivKit в Telegram-канале: http://t.me/divkit_news

Также вы можете обсуждать интересующие вас темы в сообществе пользователей DivKit в Telegram: https://t.me/divkit_community_ru

Репозиторий DivKit