Переменные
Чтобы использовать переменные, объявите их в отдельном блоке 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.