Язык шаблонов адаптивных карточек
При работе с шаблонами можно отделить данные от макета в адаптивной карточке. Язык шаблонов — это синтаксис, используемый для создания такого шаблона.
Ознакомьтесь с общими сведениями о работе с шаблонами адаптивных карточек.
Важно!
Критические изменения в версии-кандидате за май 2020 г.
Мы приложили немало усилий, чтобы этот выпуск увидел свет, и уже находимся на финишной прямой. В окончательную версию нам пришлось внести небольшие критические изменения.
Критические изменения в версии за май 2020 г.
- Синтаксис привязки изменен с
{...}
на${...}
.- Например, вместо
"text": "Hello {name}"
теперь используется"text": "Hello ${name}"
.
- Например, вместо
Привязка к данным
Создать шаблон так же просто, как заменить нестатическое содержимое карточки на выражения привязки.
Полезные данные статической карточки
{
"type": "TextBlock",
"text": "Matt"
}
Полезные данные шаблона
{
"type": "TextBlock",
"text": "${firstName}"
}
- Выражения привязки можно размещать везде, где может находиться статическое содержимое.
- Синтаксис привязки начинается с
${
и заканчивается на}
. Например, так:${myProperty}
. - Используйте запись через точку для доступа к вложенным объектам в иерархии объектов. Например, так:
${myParent.myChild}
. - Правильная обработка значений NULL гарантирует отсутствие исключений при доступе к свойству NULL в графе объектов.
- Используйте синтаксис индексатора для получения свойств по ключу или элементам в массиве. Например, так:
${myArray[0]}
.
Предоставление данных
Теперь, когда у вас есть шаблон, можно внести в него данные. Это можно сделать одним из двух способов:
- Вариант A — встроив данные в полезные данные шаблона. Данные можно встроить в полезные данные шаблона
AdaptiveCard
. Для этого просто добавьте атрибут$data
в корневой объектAdaptiveCard
. - Вариант Б — внеся данные в качестве отдельного объекта данных. В этом случае вы предоставляете два отдельных объекта пакету SDK для создания шаблонов во время его выполнения:
template
иdata
. Такой подход более популярен, так как обычно создается шаблон, динамические данные в который добавляются позже.
Вариант A — встроенные данные
{
"type": "AdaptiveCard",
"$data": {
"employee": {
"name": "Matt",
"manager": { "name": "Thomas" },
"peers": [{
"name": "Andrew"
}, {
"name": "Lei"
}, {
"name": "Mary Anne"
}, {
"name": "Adam"
}]
}
},
"body": [
{
"type": "TextBlock",
"text": "Hi ${employee.name}! Here's a bit about your org..."
},
{
"type": "TextBlock",
"text": "Your manager is: ${employee.manager.name}"
},
{
"type": "TextBlock",
"text": "3 of your peers are: ${employee.peers[0].name}, ${employee.peers[1].name}, ${employee.peers[2].name}"
}
]
}
Вариант Б — Отделение шаблона от данных
Вы можете выбрать другой, более распространенный подход: создать многократно используемый шаблон адаптивной карточки, не включая в него данные. Такой шаблон можно сохранить в файле и добавить в систему управления версиями.
Файл EmployeeCardTemplate.json
{
"type": "AdaptiveCard",
"body": [
{
"type": "TextBlock",
"text": "Hi ${employee.name}! Here's a bit about your org..."
},
{
"type": "TextBlock",
"text": "Your manager is: ${employee.manager.name}"
},
{
"type": "TextBlock",
"text": "3 of your peers are: ${employee.peers[0].name}, ${employee.peers[1].name}, ${employee.peers[2].name}"
}
]
}
Затем вы загружаете его и предоставляете данные во время выполнения с помощью пакетов SDK для работы с шаблонами.
Пример JavaScript
Использование пакета adaptivecards-templating.
var template = new ACData.Template({
// EmployeeCardTemplate goes here
});
// Specify data at runtime
var card = template.expand({
$root: {
"employee": {
"name": "Matt",
"manager": { "name": "Thomas" },
"peers": [{
"name": "Andrew"
}, {
"name": "Lei"
}, {
"name": "Mary Anne"
}, {
"name": "Adam"
}]
}
}
});
// Now you have an AdaptiveCard ready to render!
Поддержка конструктора
Конструктор адаптивных карт теперь включает поддержку шаблонов.
Чтобы поработать с конструктором, перейдите по адресу https://adaptivecards.io/designer .
- Редактор примера данных — укажите пример данных, чтобы оценить карту с привязкой к данным в режиме предварительного просмотра. На этой панели есть небольшая кнопка для заполнения структуры данных из существующего примера данных.
- Preview Mode (Режим предварительного просмотра) — нажмите кнопку на панели инструментов, чтобы переключиться между режимами редактирования и предварительного просмотра данных.
- Open Sample (Открыть пример) — нажмите эту кнопку, чтобы открыть примеры полезных данных.
Расширенная привязка
Области привязки
Есть несколько зарезервированных ключевых слов для доступа к разным областям привязки.
{
"${<property>}": "Implicitly binds to `$data.<property>`",
"$data": "The current data object",
"$root": "The root data object. Useful when iterating to escape to parent object",
"$index": "The current index when iterating"
}
Назначение элементам контекста данных
Чтобы назначить любому элементу "контекст данных", добавьте к нужному элементу атрибут $data
.
{
"type": "Container",
"$data": "${mySubObject}",
"items": [
{
"type": "TextBlock",
"text": "This TextBlock is now scoped directly to 'mySubObject': ${mySubObjectProperty}"
},
{
"type": "TextBlock",
"text": "To break-out and access the root data, use: ${$root}"
}
]
}
Повторяющиеся элементы в массиве
- Если свойство
$data
в элементе адаптивной карточки привязано к массиву, то такой элемент будет повторяться для каждого элемента массива. - Любые выражения привязки (
${myProperty}
) в значениях свойств будут относиться к отдельному элементу в массиве. - Если выполнена привязка к массиву строк, для доступа к отдельному строковому элементу используйте
${$data}
. Например, так:"text": "${$data}"
.
Например, элемент TextBlock
в приведенном ниже примере будет повторяться три раза, так как $data
является массивом. Обратите внимание, что свойство text
привязано к свойству name
отдельного объекта в этом массиве.
{
"type": "Container",
"items": [
{
"type": "TextBlock",
"$data": [
{ "name": "Matt" },
{ "name": "David" },
{ "name": "Thomas" }
],
"text": "${name}"
}
]
}
Результат:
{
"type": "Container",
"items": [
{
"type": "TextBlock",
"text": "Matt"
},
{
"type": "TextBlock",
"text": "David"
}
{
"type": "TextBlock",
"text": "Thomas"
}
]
}
Встроенные функции
Язык шаблонов нельзя считать полноценным без разнообразных вспомогательных функций. Решение для создания шаблонов адаптивных карточек основано на языке адаптивных выражений (AEL), который является открытым стандартом для объявления выражений с возможностью их оценки на разных платформах. Это — расширенный набор Logic Apps, поэтому вы можете использовать такой же синтаксис, как, например, в Power Automate.
Мы рассмотрели лишь небольшую часть встроенных функций.
Ознакомьтесь с полным списком предварительно созданных функций для языка адаптивных выражений.
Условная оценка:
- if(выражение, если_истина, если_ложь).
Пример для if
{
"type": "TextBlock",
"color": "${if(priceChange >= 0, 'good', 'attention')}"
}
Анализ JSON
- json(jsonString) — анализ строки JSON
Пример для json
Это ответ Azure DevOps для ситуации, когда свойство message
содержит сериализованную строку в формате JSON. Для обращения к значениям в этой строке следует использовать в шаблоне функцию json
.
Данные
{
"id": "1291525457129548",
"status": 4,
"author": "Matt Hidinger",
"message": "{\"type\":\"Deployment\",\"buildId\":\"9542982\",\"releaseId\":\"129\",\"buildNumber\":\"20180504.3\",\"releaseName\":\"Release-104\",\"repoProvider\":\"GitHub\"}",
"start_time": "2018-05-04T18:05:33.3087147Z",
"end_time": "2018-05-04T18:05:33.3087147Z"
}
Использование
{
"type": "TextBlock",
"text": "${json(message).releaseName}"
}
Результат
{
"type": "TextBlock",
"text": "Release-104"
}
Пользовательские функции
Пользовательские функции поддерживаются через API в пакетах SDK для создания шаблонов.
Условный макет с $when
Чтобы игнорировать элемент целиком при выполнении определенного условия, используйте свойство $when
. Если $when
имеет значение false
, такой элемент не будет отображаться для пользователя.
{
"type": "AdaptiveCard",
"$data": {
"price": "35"
},
"body": [
{
"type": "TextBlock",
"$when": "${price > 30}",
"text": "This thing is pricy!",
"color": "attention",
},
{
"type": "TextBlock",
"$when": "${price <= 30}",
"text": "Dang, this thing is cheap!",
"color": "good"
}
]
}
Компоновка шаблонов
Сейчас не поддерживается компоновка шаблона из отдельных частей. Но мы рассматриваем варианты такого механизма и скоро сообщим вам о результатах. Мы будем рады любым вашим идеям!
Примеры
Изучите обновленную страницу примеров, где представлены новые виды шаблонов карточек.