Lenguaje de plantillas de tarjetas adaptables
Las plantillas permiten separar los datos del diseño en una tarjeta adaptable. El lenguaje de plantilla es la sintaxis que se usa para crear una plantilla.
Sigue leyendo para obtener una introducción a las plantillas de tarjetas adaptables.
Importante
Cambios importantes en la versión candidata para lanzamiento de mayo de 2020
Nos hemos estado esforzando para poder publicar las plantillas y, finalmente, ya nos encontramos en la recta final. Tuvimos que realizar algunos cambios menores importantes antes de completar la versión.
Cambios importantes de mayo de 2020
- La sintaxis de enlace se cambió de
{...}
a${...}
.- Por ejemplo,
"text": "Hello {name}"
se convierte en"text": "Hello ${name}"
.
- Por ejemplo,
Enlace de datos
Escribir una plantilla es tan sencillo como reemplazar el contenido "no estático" de la tarjeta por "expresiones de enlace".
Carga de la tarjeta estática
{
"type": "TextBlock",
"text": "Matt"
}
Carga de plantilla
{
"type": "TextBlock",
"text": "${firstName}"
}
- Las expresiones de enlace se pueden colocar prácticamente en cualquier lugar en el que pueda haber contenido estático.
- La sintaxis de enlace comienza con
${
y termina con}
. Por ejemplo,${myProperty}
- Usa Dot-notation para acceder a los subobjetos de una jerarquía de objetos. Por ejemplo,
${myParent.myChild}
- El control de valores NULL correctos garantiza que no obtendrás excepciones si accedes a una propiedad nula en un gráfico de objetos.
- Usa la sintaxis del indexador para recuperar propiedades por clave o elementos de una matriz. Por ejemplo,
${myArray[0]}
Aprovisionamiento de datos
Ahora que tienes una plantilla, querrás proporcionar los datos para completarla. Para ello, tienes dos opciones:
- Opción A: de forma alineada en la carga de la plantilla. Puedes proporcionar los datos alineados en la carga de la plantilla
AdaptiveCard
. Para ello, simplemente agrega un atributo$data
al objeto raízAdaptiveCard
. - Opción B: como un objeto de datos independiente. Con esta opción, proporcionas dos objetos independientes al SDK de plantillas en tiempo de ejecución:
template
ydata
. Este será el enfoque más común, ya que normalmente crearás una plantilla y querrás proporcionar datos dinámicos más adelante.
Opción A: datos alineados
{
"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}"
}
]
}
Opción B: Separación de la plantilla de los datos
como alternativa (y más probablemente), crearás una plantilla de tarjeta reutilizable sin incluir los datos. Esta plantilla se puede almacenar como archivo y agregar al control de origen.
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}"
}
]
}
Luego, puedes cargarla y proporcionar los datos en tiempo de ejecución mediante los SDK de plantillas.
Ejemplo de JavaScript
Uso del paquete 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!
Compatibilidad del diseñador
El diseñador de tarjetas adaptables se ha actualizado para admitir plantillas.
Pruébalo en https://adaptivecards.io/designer
- Editor de datos de ejemplo: Especifique los datos de ejemplo aquí para ver la tarjeta enlazada a datos en "Modo de vista previa". Hay un botón pequeño en este panel para rellenar la estructura de datos a partir de los datos de ejemplo existentes.
- Modo de vista previa: presiona el botón de la barra de herramientas para alternar entre la experiencia de edición y la experiencia de vista previa de datos de ejemplo.
- Open sample (Abrir ejemplo): haz clic en este botón para abrir varias cargas de ejemplo.
Enlace avanzado
Ámbitos de enlace
Hay algunas palabras clave reservadas para acceder a distintos ámbitos de enlace.
{
"${<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"
}
Asignar un contexto de datos a elementos
Para asignar un "contexto de datos" a cualquier elemento, agrega un atributo $data
al elemento.
{
"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}"
}
]
}
Repetición de elementos en una matriz
- Si la propiedad
$data
de un elemento de tarjeta adaptable está enlazada con una matriz, el propio elemento se repetirá para cada elemento de la matriz. - Todas las expresiones de enlace (
${myProperty}
) usadas en los valores de la propiedad se limitarán al elemento individual dentro de la matriz. - Si el enlace es a una matriz de cadenas, usa
${$data}
para acceder al elemento de cadena individual. Por ejemplo,"text": "${$data}"
Por ejemplo, el elemento TextBlock
siguiente se repetirá 3 veces, ya que su valor de $data
es una matriz. Observa cómo la propiedad text
se enlaza con la propiedad name
de un objeto individual dentro de la matriz.
{
"type": "Container",
"items": [
{
"type": "TextBlock",
"$data": [
{ "name": "Matt" },
{ "name": "David" },
{ "name": "Thomas" }
],
"text": "${name}"
}
]
}
Elemento resultante:
{
"type": "Container",
"items": [
{
"type": "TextBlock",
"text": "Matt"
},
{
"type": "TextBlock",
"text": "David"
}
{
"type": "TextBlock",
"text": "Thomas"
}
]
}
Funciones integradas
Ningún lenguaje de plantillas se considera completo sin un conjunto avanzado de funciones auxiliares. Las plantillas de tarjetas adaptables se basan en Adaptive Expression Language (AEL), que es un estándar abierto para declarar expresiones que se pueden evaluar en muchas plataformas diferentes. Además, se trata de un supraconjunto adecuado de "Logic Apps", por lo que puedes usar una sintaxis similar a la de Power Automate, etc.
Esta es solo una pequeña muestra de las funciones integradas.
Consulta la lista completa de funciones precompiladas de Adaptive Expression Language.
Evaluación condicional
- if(expresión, valorVerdadero, valorFalso)
Ejemplo de if
{
"type": "TextBlock",
"color": "${if(priceChange >= 0, 'good', 'attention')}"
}
Análisis de JSON
- json(jsonString): analizar una cadena JSON
Ejemplo de json
Se trata de una respuesta de Azure DevOps en la que la propiedad message
es una cadena serializada en JSON. Para acceder a los valores de la cadena, es necesario usar la función json
de la plantilla.
Datos
{
"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"
}
Uso
{
"type": "TextBlock",
"text": "${json(message).releaseName}"
}
Elemento resultante
{
"type": "TextBlock",
"text": "Release-104"
}
Funciones personalizadas
Las funciones personalizadas se admiten mediante las API de los SDK de plantillas.
Diseño condicional con $when
Para quitar un elemento completo si se cumple una condición, usa la propiedad $when
. Si $when
se evalúa como false
, el elemento no se mostrará al usuario.
{
"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"
}
]
}
Composición de plantillas
Actualmente, no se admite la composición de "partes" de plantillas. Pero estamos explorando opciones y esperamos tener novedades pronto. Agradecemos cualquier idea al respecto.
Ejemplos
Examina la página de ejemplos actualizada para explorar todos los tipos de nuevas tarjetas con plantilla.