共用方式為


自適應卡片範本語言

在你的自適應卡中,模板化能將資料版面分開。 範本語言是用來撰寫範本的語法。

請閱讀此文以了解 自適應卡片模板的概述

這很重要

2020 年 5 月版本候選版的重大變更

我們一直在努力推出版模功能,終於進入最後階段了! 隨著發行接近尾聲,我們不得不做一些小的破壞性修改。

截至2020年5月的重大變更

  1. 綁定語法由 {...} 改為 ${...}
    • 例如: "text": "Hello {name}" 變成 "text": "Hello ${name}"

資料綁定

撰寫範本很簡單,只要將卡片上的「非靜態」內容替換為「綁定表達式」即可。

靜態卡片有效載荷

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

範本有效載荷

{
   "type": "TextBlock",
   "text": "${firstName}"
}
  • 綁定表達式幾乎可以放置在靜態內容所在的任何地方
  • 綁定語法從${開始,並以}結束。 例如,${myProperty}
  • 使用 點符號 來存取物件階層的子物件。 例如,${myParent.myChild}
  • 優雅的 null 處理確保你在物件圖中存取 null 屬性時不會遇到異常
  • 使用 Indexer 語法 來透過鍵或陣列中的項目取得屬性。 例如,${myArray[0]}

提供資料

現在你有了範本,就需要提供讓它完整的資料。 你有兩個選擇:

  1. 選項A:內嵌於模板有效載荷中。 你可以直接在AdaptiveCard 範本的有效載荷中嵌入提供的資料。 要做到這點,只要在根$data物件上加入AdaptiveCard一個屬性即可。
  2. 選項B:作為獨立的資料物件。 使用此選項時,你會在執行時為 模板 SDK 提供兩個獨立物件:the templatedata. 這是比較常見的方法,因為通常你會先建立範本,之後再提供動態資料。

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

選項B:將範本與資料分離

另外(更常見的是),你會建立一個可重複使用的卡片範本,但不包含資料。 這個範本可以儲存成檔案並加入原始碼控制。

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

接著載入並在執行時使用Templating SDKs提供資料。

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!

設計師支援

Adaptive Card Designer 已更新以支援範本功能。

試試看: https://adaptivecards.microsoft.com/designer

圖片

  • 範例資料編輯器 - 在此指定範例資料,以便在「預覽模式」時查看資料綁定卡片。這個窗格裡有一個小按鈕,可以從現有的樣本資料中填充資料結構。
  • 預覽模式 - 按下工具列按鈕可在編輯體驗與範例資料預覽體驗間切換
  • 開啟樣本 - 點擊此按鈕開啟各種樣本載荷

進階綁定

繫結範圍

有幾個保留關鍵字可用來存取不同的綁定範圍。

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

在陣列中重複項目

  • 如果 Adaptive Card 元素 $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)之上,AEL 是一個開放標準,用於宣告可在多種不同平台上評估的表達式。 而且它是「邏輯應用程式」的正式超集,所以你可以用類似 Power Automate 等軟體的語法。

這只是內建功能的一小部分。

請查看完整的 自適應表達式語言預建函式清單。

條件式評估

  • if(expressiontrueValuefalseValue

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

自訂函式

自訂函式可透過 模板 SDK 中的 API 支援。

使用條件式佈局 $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"
        }
    ]
}

撰寫模板

目前尚無支援將範本「部分」組合在一起。 但我們正在探索各種選項,並希望很快能分享更多資訊。 歡迎大家分享任何想法!

範例

瀏覽更新後 的範例頁面 ,探索各種新的模板卡牌。