Переменные

Чтобы использовать переменные, объявите их в отдельном блоке variables в корне карточки. При объявлении переменной укажите параметры:

  • name — имя, может состоять из латинских букв разных регистров, цифр и символов _ и .. Не может начинаться с цифры или с точки.
  • type — тип переменной. См. Типы данных.
  • value — значение по умолчанию.

Например:

{
    "variables": [
        {
            "name": "subscribed",
            "type": "boolean",
            "value": true
        }
    ],
}

Типы данных

Поддерживаемые типы данных:

  • логический: boolean
  • строковый: string
  • целочисленный: integer
  • число с плавающей точкой: number
  • цвет: color
  • ссылка на ресурс: url
  • словарь: dict
  • массив: array
Примеры объявления переменных
{
    "variables": [
        {
            "name": "subscribed",
            "type": "boolean",
            "value": true
        },
        {
            "name": "likes",
            "type": "integer",
            "value": 0
        },
        {
            "name": "black",
            "type": "color",
            "value": "#f000"
        },
        {
            "name": "username",
            "type": "string",
            "value": "unknown"
        }
    ],
    "states": [ ... ]
}

Словари

В качестве переменной можно объявлять словари — произвольные JSON-объекты, внутри которых могут храниться любые другие типы переменных.
Например, их удобно использовать для объявления палитры и получать из нее значения в зависимости от темы приложения:

"variables": [
  {
    "name": "palette",
    "type": "dict",
    "value": {
      "light": {
        "text_color": "#ffffff",
        "text_background": "#0077FF"
      },
      "dark": {
        "text_color": "#000000",
        "text_background": "#0077FF"
      },
      "big": {
        "text_size": 20
      },
      "small": {
        "text_size": 16
      }
    }
  },
  {
    "name": "app_theme",
    "type": "string",
    "value": "light"
  },
  {
    "name": "font_size",
    "type": "string",
    "value": "small"
  }
]

Словарь не может самостоятельно определять типы, поэтому нужно правильно выбирать функции для того, чтобы получить переменную из словаря:

getIntegerFromDict(dict_name, path_to_value)
getNumberFromDict(dict_name, path_to_value)
getStringFromDict(dict_name, path_to_value)
getColorFromDict(dict_name, path_to_value)
getUrlFromDict(dict_name, path_to_value)
getBooleanFromDict(dict_name, path_to_value)
getOptIntegerFromDict(fallback, dict_name, path_to_value)
getOptNumberFromDict(fallback, dict_name, path_to_value)
getOptStringFromDict(fallback, dict_name, path_to_value)
getOptColorFromDict(fallback, dict_name, path_to_value)
getOptUrlFromDict(fallback, dict_name, path_to_value)
getOptBooleanFromDict(fallback, dict_name, path_to_value)

В объявленном словаре из примера значения цветов и размера шрифта можно использовать так:

"background": [
  {
    "type": "solid",
    "color": "@{getColorFromDict(palette, app_theme, 'text_background')}"
  }
],
"font_size": "@{getIntegerFromDict(palette, font_size, 'text_size')}",
"text_color": "@{getColorFromDict(palette, app_theme, 'text_color')}"
Посмотреть интерактивный пример

Массивы

Массивы содержат произвольные JSON-объекты.

"variables": [
  {
    "type": "array",
    "name": "array",
    "value": [
      "string",
       123,
      "@{expression}"
    ]
  }
]

Массив, как и словарь, не может автоматически определять типы переменных, которые хранятся внутри него, поэтому нужно правильно выбирать функции для того, чтобы получить значение из массива:

getIntegerFromArray(array, index)
getNumberFromArray(array, index)
getStringFromArray(array, index)
getColorFromArray(array, index)
getUrlFromArray(array, index)
getBooleanFromArray(array, index)
getArrayFromArray(array, index)
getDictFromArray(array, index)
getOptIntegerFromArray(array, index, fallback)
getOptNumberFromArray(array, index, fallback)
getOptStringFromArray(array, index, fallback)
getOptColorFromArray(array, index, fallback)
getOptUrlFromArray(array, index, fallback)
getOptBooleanFromArray(array, index, fallback)
getOptArrayFromArray(array, index, fallback)
getOptDictFromArray(array, index, fallback)

getArrayLength(array)

Если тип функции выбран неправильно или произошел выход за границы массива, возникнет ошибка. В этом случае можно использовать функцию getOpt* вместо get*, тогда вместо ошибки возвратится fallback значение.

Посмотреть интерактивный пример

Изменение значений переменных

Для изменения значения переменной доступно действиеset_variable. Например:

div-action://set_variable?name=common_text_size&value=17

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

Изменить значения переменных также можно через SDK (в Android с помощью DivView#setVariable ).

Примечание

Важно, чтобы тип нового значения совпадал с типом переменной, иначе будет невозможно применить значение.

Примеры:

  • изменить значение переменной с плавающей точкой:

    div-action://set_variable?name=price&value=3.889
    
  • изменить значение логической переменной:

    • значение true: div-action://set_variable?name=is_liked&value=1
    • значение false: div-action://set_variable?name=is_liked&value=0
  • изменить значение переменной типа color на зеленый цвет:

    div-action://set_variable?name=color_variable&value=@{encodeUri('#ff00ff00')}
    

Глобальные переменные

Переменные, которые объявляются в верстке, являются локальными и недоступными извне. Для совместного использования переменных между разными верстками нужно использовать глобальные переменные.

Для этого объявите DivVariableController на клиенте и передайте в него переменные, к которым нужно обращаться из верстки.

Пример для Android

Объявим DivVariableController при создании DivConfiguration:

val variableController = DivVariableController()
val configuration = DivConfiguration.Builder(imageLoader)
    .divVariableController(variableController)
    .build()

Теперь в контроллер можно передать переменную. Для примера передадим строковую переменную app_theme:

val theme = Variable.StringVariable("app_theme", "light")
variableController.putOrUpdate(theme)

Теперь во всех Div2View, созданных с помощью данной DivConfiguration, будет доступна переменная app_theme. Чтобы изменить значение переменной, в коде можно использовать метод DivVariable#set. Если эта переменная уже объявленна в контроллере — ее значение также обновится.

Пример для iOS

Объявим DivVariableController в DivKitComponents:

let variablesStorage = DivVariablesStorage()
let divkitComponents = DivKitComponents(variablesStorage: variablesStorage)

Теперь в контроллер можно передать переменную. Для примера передадим словарь с палитрой:

let themeVariable: DivVariables = [
  DivVariableName(rawValue: "palette"): .dict([
    "text_color": "#ffffff",
    "text_background": "#0077FF"
  ])
]
variablesStorage.put(themeVariable)

Теперь во всех Div2View, созданных с помощью данного DivKitComponent, будет доступна переменная pallete.

Пример для Web

Создадим GlobalVariablesController:

import {createVariable, createGlobalVariablesController} from '@divkitframework/divkit';

const controller = createGlobalVariablesController();

Теперь в контроллер можно передать переменную, например словарь с палитрой:

const palette = createVariable('palette', 'dict', {
  "text_color": "#ffffff",
  "text_background": "#0077FF"
});
controller.setVariable(palette);

Теперь во всех экземплярах класса, созданных с использованием данного controller, будет доступна переменная pallete.

Внимание

Локальные переменные имеют больший приоритет, чем глобальные. Если объявить в верстке локальную переменную с тем же названием, что и у глобальной, то глобальная переменная станет недоступна. Также изменение глобальной переменной из верстки поменяет ее и в DivVariableController, то есть и во всех остальных верстках, где используется эта переменная.

Выполнение действий при изменении значений переменных

После изменения значения переменной, кроме обновления всех свойств, в которых используется переменная, можно выполнить любое количество действий. Для этого добавьте описание триггера в блоке variable_triggers:

  • Параметр condition — условие выполнения действия. Может содержать логическое выражение с использованием переменных или события, по которым будет запущен триггер.

  • Параметр mode — определяет, в каком случае срабатывает действие:

    • on_condition — действие срабатывает, если при изменении значения переменной стало выполняться условие (до этого условие не выполнялось);
    • on_variable — действие срабатывает каждый раз, если при изменении значения переменной условие выполняется.

    Например, переменные меняются несколько раз и condition последовательно принимает значения true → true → false → true. При использовании значения on_condition действие сработает 2 раза, при использовании значения on_variable — 3 раза.

  • Параметр actions — описание действий, которые требуется выполнить при выполнении условия.

Ограничения:

  • Условия без использования переменных (к примеру "condition": "@{1 == 1}") или с функциями, не зависящими от переменных, не будут работать, так как без переменных не ясно, когда именно следует запускать проверку условия.
  • Триггер не будет срабатывать, если в условии сравниваемые между собой сущности будут иметь разные типы (к примеру, переменная логического типа сравнивается с переменной типа integer).

Например:

{
    "states": { ... },
    "variables": { ... },
    "variable_triggers": [
        {
            "condition": "@{liked}",
            "actions": [
                {
                    "url": "div-action://set_variable?name=total_likes&value=@{sum(total_likes, 1)}"
                }
            ]
        },
        {
            "condition": "@{subscribed && !liked}",
            "mode": "on_condition",
            "actions": [
                {
                    "url": "div-action://set_state?state_id=0/subscriptions/expanded"
                },
                {
                    "log_id": "common_posts_shown",
                    "url": "div-action://set_state?state_id=0/common_posts/collapsed"
                }
            ]
        },
        {
            "condition": "@{total_likes > 100 || user_name == 'John'}",
            "mode": "on_variable",
            "actions": [ ... ]
        }
  ]
}

В примере выше первый триггер будет запускать действие, которое увеличивает значение переменной total_likes каждый раз, когда значение переменной liked сменится с false на true . По такой же логике будет работать и второй триггер.

Третий триггер, благодаря параметру "mode": "on_variable", будет запускаться каждый раз при изменении значений переменных и выполнении условия в condition .

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

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

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

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

Предыдущая