在你的自適應卡中,模板化能將資料與版面分開。 範本語言是用來撰寫範本的語法。
請閱讀此文以了解 自適應卡片模板的概述
這很重要
2020 年 5 月版本候選版的重大變更
我們一直在努力推出版模功能,終於進入最後階段了! 隨著發行接近尾聲,我們不得不做一些小的破壞性修改。
截至2020年5月的重大變更
- 綁定語法由
{...}改為${...}- 例如:
"text": "Hello {name}"變成"text": "Hello ${name}"
- 例如:
資料綁定
撰寫範本很簡單,只要將卡片上的「非靜態」內容替換為「綁定表達式」即可。
靜態卡片有效載荷
{
"type": "TextBlock",
"text": "Matt"
}
範本有效載荷
{
"type": "TextBlock",
"text": "${firstName}"
}
- 綁定表達式幾乎可以放置在靜態內容所在的任何地方
- 綁定語法從
${開始,並以}結束。 例如,${myProperty} - 使用 點符號 來存取物件階層的子物件。 例如,
${myParent.myChild} - 優雅的 null 處理確保你在物件圖中存取 null 屬性時不會遇到異常
- 使用 Indexer 語法 來透過鍵或陣列中的項目取得屬性。 例如,
${myArray[0]}
提供資料
現在你有了範本,就需要提供讓它完整的資料。 你有兩個選擇:
-
選項A:內嵌於模板有效載荷中。 你可以直接在
AdaptiveCard範本的有效載荷中嵌入提供的資料。 要做到這點,只要在根$data物件上加入AdaptiveCard一個屬性即可。 -
選項B:作為獨立的資料物件。 使用此選項時,你會在執行時為 模板 SDK 提供兩個獨立物件:the
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}"
}
]
}
選項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 範例
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 已更新以支援範本功能。
- 範例資料編輯器 - 在此指定範例資料,以便在「預覽模式」時查看資料綁定卡片。這個窗格裡有一個小按鈕,可以從現有的樣本資料中填充資料結構。
- 預覽模式 - 按下工具列按鈕可在編輯體驗與範例資料預覽體驗間切換
- 開啟樣本 - 點擊此按鈕開啟各種樣本載荷
進階綁定
繫結範圍
有幾個保留關鍵字可用來存取不同的綁定範圍。
{
"${<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(expression, trueValue, falseValue)
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"
}
]
}
撰寫模板
目前尚無支援將範本「部分」組合在一起。 但我們正在探索各種選項,並希望很快能分享更多資訊。 歡迎大家分享任何想法!
範例
瀏覽更新後 的範例頁面 ,探索各種新的模板卡牌。