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

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

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

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

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

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