Partilhar via


Linguagem de Modelos de Cartões Adaptáveis

O template permite a separação dos dados do layout no seu Cartão Adaptativo. A linguagem de templates é a sintaxe usada para criar um template.

Por favor, leia isto para uma visão geral do Adaptive Card Templating

Importante

Alterações recentes no Candidato a Lançamento de maio de 2020

Trabalhámos arduamente para lançar a funcionalidade de templates e finalmente estamos na reta final! Tivemos de fazer algumas alterações menores à medida que nos aproximamos do lançamento.

Alterações recentes até maio de 2020

  1. A sintaxe de ligação mudou de {...} para ${...}
    • Por exemplo: "text": "Hello {name}" torna-se "text": "Hello ${name}"

Ligação a dados

Escrever um modelo é tão simples como substituir o conteúdo "não estático" do seu cartão por "expressões de associação".

Carga útil de cartão estático

{
   "type": "TextBlock",
   "text": "Matt"
}

Carga útil modelo

{
   "type": "TextBlock",
   "text": "${firstName}"
}
  • As expressões de ligação podem ser colocadas praticamente em qualquer lugar onde o conteúdo estático pode ser colocado.
  • A sintaxe de ligação começa com ${ e termina em }. Por exemplo, ${myProperty}
  • Use notação de pontos para aceder a subobjetos de uma hierarquia de objetos. Por exemplo, ${myParent.myChild}
  • Uma gestão elegante de null garante que não terá exceções se aceder a uma propriedade null num grafo de objetos
  • Use a sintaxe do indexador para recuperar propriedades por chave ou itens num array. Por exemplo, ${myArray[0]}

Fornecimento dos dados

Agora que tem um modelo, vai querer fornecer os dados que o tornam completo. Tens duas opções para isso:

  1. Opção A: Integrada na carga útil do modelo. Pode fornecer os dados de forma incorporada no conteúdo do AdaptiveCard modelo. Para isso, basta adicionar um $data atributo ao objeto raiz AdaptiveCard .
  2. Opção B: Como um objeto de dados separado. Com esta opção, fornece dois objetos separados ao SDK de Templating em tempo de execução: o template e o data. Esta será a abordagem mais comum, pois normalmente cria um modelo e quere fornecer dados dinâmicos mais tarde.

Opção A: Dados em linha

{
    "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}"
        }
    ]
}

Opção B: Separar o modelo dos dados

Alternativamente (e mais provavelmente), vais criar um modelo de cartão reutilizável sem incluir os dados. Este modelo podia ser armazenado como um ficheiro e adicionado ao controlo de versão.

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}"
        }
    ]
}

Depois carrega-o e fornece os dados em tempo de execução usando os SDKs de Templação.

Exemplo de JavaScript

Usando o pacote 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!

Apoio ao Designer

O Adaptive Card Designer foi atualizado para suportar modelos.

Experimente em: https://adaptivecards.microsoft.com/designer

Imagem

  • Editor de Dados de Exemplo - Especifique aqui dados de amostra para visualizar o cartão vinculado aos dados quando estiver em "Modo de Pré-visualização". Existe um pequeno botão neste painel para preencher a Estrutura de Dados a partir dos dados de amostra existentes.
  • Modo de Pré-visualização - Pressione o botão da barra de ferramentas para alternar entre a experiência de edição e a experiência de pré-visualização de dados de amostra
  • Abrir Exemplo - clique neste botão para abrir vários exemplos de cargas úteis

Encadernação avançada

Âmbitos de enlace

Existem algumas palavras-chave reservadas para aceder a vários contextos de ligação.

{
    "${<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"
}

Atribuição de um contexto de dados a elementos

Para atribuir um "contexto de dados" a qualquer elemento, adiciona um $data atributo ao 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}"
        }
    ]
}

Itens repetidos num array

  • Se a propriedade de $data um elemento de Cartão Adaptativo estiver ligada a um array, então o próprio elemento será repetido para cada item do array.
  • Quaisquer expressões de ligação (${myProperty}) usadas nos valores de propriedades serão atribuídas ao item individual dentro do array.
  • Se estiver a ligar a um array de strings, use ${$data} para aceder ao elemento individual da string. Por exemplo, "text": "${$data}"

Por exemplo, o TextBlock que se segue será repetido 3 vezes, pois $data é um array. Note como a text propriedade está ligada à name propriedade de um objeto individual dentro do array.

{
    "type": "Container",
    "items": [
        {
            "type": "TextBlock",
            "$data": [
                { "name": "Matt" }, 
                { "name": "David" }, 
                { "name": "Thomas" }
            ],
            "text": "${name}"
        }
    ]
}

Resultando em:

{
    "type": "Container",
    "items": [ 
        {
            "type": "TextBlock",
            "text": "Matt"
        },
        {
            "type": "TextBlock",
            "text": "David"
        }
        {
            "type": "TextBlock",
            "text": "Thomas"
        }
    ]
}

Funções incorporadas

Nenhuma linguagem de templates está completa sem um conjunto rico de funções auxiliares. O Adaptive Card Templating é construído sobre a Adaptive Expression Language (AEL), que é um padrão aberto para declarar expressões que pode ser avaliado em várias plataformas diferentes. E é um superconjunto adequado de "Logic Apps", por isso podes usar uma sintaxe semelhante à do Power Automate, etc.

Isto é apenas uma pequena amostra das funções incorporadas.

Consulte a lista completa de funções pré-construídas da Adaptive Expression Language.

Avaliação condicional

  • se(expressão, valorVerdadeiro, valorFalso)

if Exemplo

{
    "type": "TextBlock",
    "color": "${if(priceChange >= 0, 'good', 'attention')}"
}

Análise JSON

  • json(jsonString) - Analisar uma string JSON

json Exemplo

Esta é uma resposta Azure DevOps onde a message propriedade é uma string serializada em JSON. Para aceder aos valores dentro da cadeia, precisamos de usar a json função do nosso modelo.

Dados

{
    "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"
}

Utilização

{
    "type": "TextBlock",
    "text": "${json(message).releaseName}"
}

Resultando em

{
    "type": "TextBlock",
    "text": "Release-104"
}

Funções personalizadas

Funções personalizadas são suportadas através de APIs nos SDKs de Templados.

Disposição condicional com $when

Para eliminar um elemento inteiro se uma condição for cumprida, use a $when propriedade. Se $when for avaliado como false, o elemento não será visível para o utilizador.

{
    "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"
        }
    ]
}

Modelos de composição

Atualmente, não existe suporte para compor "partes" modelo em conjunto. Mas estamos a explorar opções e esperamos partilhar mais em breve. Qualquer opinião aqui é bem-vinda!

Examples

Consulte a página atualizada de Exemplos para explorar todo o tipo de novos cartões com modelos.