Compartilhar via


Linguagem de modelo de cartões adaptáveis

A modelagem permite a separação de dados do layout em seu Cartão Adaptável. A linguagem de modelo é a sintaxe usada para criar um modelo.

Leia isso para obter uma visão geral da Modelagem de Cartão Adaptável

Importante

Alterações significativas no candidato à versão de maio de 2020

Estamos trabalhando arduamente para liberar o uso de templates e finalmente estamos na reta final! Tivemos que fazer algumas pequenas mudanças à medida que fechamos o lançamento.

Alterações significativas a partir de maio de 2020

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

Vinculação a dados

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

Carga de dados do cartão estático

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

Conteúdo do modelo

{
   "type": "TextBlock",
   "text": "${firstName}"
}
  • Expressões de associação podem ser colocadas praticamente em qualquer lugar onde se pode ter conteúdo estático.
  • A sintaxe de associação começa com ${ e termina com }. Por exemplo, ${myProperty}
  • Use a notação de ponto (Dot-notation) para acessar sub-objetos de uma hierarquia de objetos. Por exemplo, ${myParent.myChild}
  • O tratamento elegante de nulos garante que você não irá receber exceções ao acessar uma propriedade nula em um gráfico de objetos.
  • Use a sintaxe do Indexador para recuperar propriedades por chave ou itens em uma matriz. Por exemplo, ${myArray[0]}

Fornecendo os dados

Agora que você tem um modelo, você desejará fornecer os dados que os tornam completos. Você tem duas opções para fazer isso:

  1. Opção A: embutido no conteúdo do modelo. Você pode fornecer os dados embutidos na carga útil do modelo AdaptiveCard. Para fazer isso, basta adicionar um $data atributo ao objeto raiz AdaptiveCard .
  2. Opção B: como um objeto de dados separado. Com essa opção, você fornece dois objetos separados para o SDK de Modelagem em runtime: o template .data Essa será a abordagem mais comum, pois normalmente você criará um modelo e desejará fornecer dados dinâmicos mais tarde.

Opção A: dados embutidos

{
    "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: separando o modelo dos dados

Como alternativa (e mais provável), você criará um modelo de cartão reutilizável sem incluir os dados. Esse modelo pode ser armazenado como um arquivo e adicionado ao controle do código-fonte.

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

Em seguida, carregue-os e forneça os dados em runtime usando os SDKs de Modelagem.

Exemplo do 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!

Suporte ao Designer

O Designer de Cartão Adaptável foi atualizado para dar suporte à modelagem.

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

Imagem

  • Editor de Dados de Exemplo – Especifique os dados de exemplo aqui para exibir o cartão associado a dados quando estiver no "Modo de Visualização". Há um pequeno botão neste painel para preencher a Estrutura de Dados dos dados de exemplo existentes.
  • Modo de Visualização – Pressione o botão barra de ferramentas para alternar entre a experiência de edição e a experiência de visualização de dados de exemplo
  • Abrir Exemplo – clique neste botão para abrir vários conteúdos de exemplo

Vinculação avançada

Escopos de associação

Há algumas palavras-chave reservadas para acessar vários escopos de associaçã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"
}

Atribuindo um contexto de dados a elementos

Para atribuir um "contexto de dados" a qualquer elemento, adicione 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}"
        }
    ]
}

Repetindo itens em uma matriz

  • Se a propriedade de $data um elemento de Cartão Adaptável estiver associada a uma matriz, o elemento em si será repetido para cada item na matriz.
  • Todas as expressões de associação (${myProperty}) usadas em valores de propriedade serão definidas para o item individual dentro da matriz.
  • Se associar a uma matriz de cadeias de caracteres, use ${$data} para acessar o elemento de cadeia de caracteres individual. Por exemplo, "text": "${$data}"

Por exemplo, o TextBlock abaixo será repetido três vezes, pois é $data uma matriz. Observe como a text propriedade está associada à name propriedade de um objeto individual dentro da matriz.

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

Nenhuma linguagem de modelagem é concluída sem um conjunto avançado de funções auxiliares. A Modelagem de Cartão Adaptável é criada com base na Linguagem de Expressão Adaptável (AEL), que é um padrão aberto para declarar expressões que podem ser avaliadas em várias plataformas diferentes. E é um superconjunto adequado de "Aplicativos Lógicos", para que você possa usar sintaxe semelhante à do Power Automate etc.

Essa é apenas uma pequena amostragem das funções internas.

Confira a lista completa das funções pré-criadas da Linguagem de Expressão Adaptável.

Avaliação condicional

  • if(expression, trueValue, falseValue)

if Exemplo

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

Analisando JSON

  • json(jsonString) – Analisar uma cadeia de caracteres JSON

json Exemplo

Essa é uma resposta do Azure DevOps em que a message propriedade é uma cadeia de caracteres serializada por JSON. Para acessar valores dentro da cadeia de caracteres, precisamos usar a json função em 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"
}

Usage

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

Resultando em

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

Funções personalizadas

Há suporte para funções personalizadas por meio de APIs nos SDKs de Modelagem.

Layout condicional com $when

Para remover um elemento inteiro se uma condição for atendida, use a $when propriedade. Se $when for avaliado para false o elemento não será exibido para o usuário.

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

Compondo modelos

Atualmente, não há suporte para compor "partes" do modelo em conjunto. Mas estamos explorando opções e esperamos compartilhar mais em breve. Todos os pensamentos aqui bem-vindos!

Exemplos

Navegue pela página Exemplos atualizados para explorar todos os tipos de novos cartões modelo.