Azure DevOps 服務 |Azure DevOps Server |Azure DevOps Server 2022 |Azure DevOps Server 2020
模態對話框是一種強大的方法,可在 Azure DevOps 擴充功能中建立專注的使用者體驗。 對話服務允許你呈現一個模態對話框,阻擋使用者與整個 Azure DevOps 介面的互動,直到對話被關閉為止。 此動作可確保使用者完成重要工作或提供必要的資訊。
於您的擴充功能中使用模態對話框來:
- 透過表單收集使用者輸入
- 顯示重要動作的確認訊息
- 顯示需要使用者注意的詳細資訊
- 引導使用者完成多個步驟的流程
這很重要
當你建立 modal 對話框時,它們會阻擋與整個 Azure DevOps 頁面的互動,不只是你的擴充功能。 此方法提供真正的模態體驗,但您應謹慎使用,以避免中斷使用者的工作流程。
先決條件
| 類別 | 要求 | 詳細資訊 |
|---|---|---|
| 擴充功能設定 | 工作擴展專案 | 有效的 vss-extension.json 資訊清單檔案 |
| Marketplace 註冊 | 向 Visual Studio Marketplace 註冊以進行測試和部署的延伸模組 | |
| 開發知識 | 瞭解 Azure DevOps 擴充功能開發基本概念 | |
| 開發環境 | Node.js 和 npm | Node.js 已安裝 npm 的 14 版或更新版本 |
| 程式代碼編輯器 | 建議使用 Visual Studio Code 或其他 IDE | |
| Azure DevOps 訪問 | Azure DevOps 組織的存取權以進行測試 | |
| 必要套件 | 擴展 SDK | 安裝: npm install azure-devops-extension-sdk |
| 擴充 API | 安裝: npm install azure-devops-extension-api |
|
| 延伸模組許可權 | 指令清單範圍 | 在 vss-extension.json 中包括適當的範圍,例如:"vso.work"、"vso.project" |
| SDK 匯入 | 必要模組 | 匯入SDK和服務: import * as SDK from "azure-devops-extension-sdk" |
對話框內容
若要開始,請在延伸模組指令清單中宣告 類型 ms.vss-web.control 的貢獻。 此貢獻代表對話框內顯示的內容。
{
"id": "registration-form",
"type": "ms.vss-web.control",
"description": "The content to be displayed in the dialog",
"targets": [],
"properties": {
"uri": "registration-form.html"
}
}
uri 屬性參考在對話框內容區域內顯示的頁面:
<!DOCTYPE html>
<html>
<head>
<script src="node_modules/azure-devops-extension-sdk/lib/SDK.js"></script>
</head>
<body>
<h2 id="header">Register now</h2>
<p>
<label>Name:</label>
<input id="inpName" />
</p>
<p>
<label>Date of birth:</label>
<input id="inpDob" />
</p>
<p>
<label>Email address:</label>
<input id="inpEmail" />
</p>
<script type="module">
import * as SDK from "azure-devops-extension-sdk";
SDK.init();
const registrationForm = (function() {
const callbacks = [];
function inputChanged() {
// Execute registered callbacks
for(let i = 0; i < callbacks.length; i++) {
callbacks[i](isValid());
}
}
function isValid() {
// Check whether form is valid or not
return !!(name.value) && !!(dateOfBirth.value) && !!(email.value);
}
function getFormData() {
// Get form values
return {
name: name.value,
dateOfBirth: dateOfBirth.value,
email: email.value
};
}
const name = document.getElementById("inpName");
const dateOfBirth = document.getElementById("inpDob");
const email = document.getElementById("inpEmail");
name.addEventListener("change", inputChanged);
dateOfBirth.addEventListener("change", inputChanged);
email.addEventListener("change", inputChanged);
return {
isFormValid: function() {
return isValid();
},
getFormData: function() {
return getFormData();
},
attachFormChanged: function(cb) {
callbacks.push(cb);
}
};
})();
// Register form object to be used across this extension
SDK.register("registration-form", registrationForm);
</script>
</body>
</html>
顯示對話框
要顯示對話框(例如使用者在工具列或選單中選擇動作時),請在對話服務的實例中呼叫該 openDialog 函式:
import * as SDK from "azure-devops-extension-sdk";
SDK.getService(SDK.CommonServiceIds.Dialog).then((dialogService) => {
const extensionCtx = SDK.getExtensionContext();
// Build absolute contribution ID for dialogContent
const contributionId = `${extensionCtx.publisherId}.${extensionCtx.extensionId}.registration-form`;
// Show dialog
const dialogOptions = {
title: "My Dialog",
width: 800,
height: 600
};
dialogService.openDialog(contributionId, dialogOptions);
});
進階對話框功能
選取 [確定] 按鈕時,可以呼叫函式。 您可以在顯示對話方塊時提供的選項中進行設定 getDialogResult 來指定此功能。
如果呼叫 getDialogResult 傳回非空值,則此值會傳遞至由 okCallback 指定的函式(也在選項中),並關閉對話方塊。
在此範例中,當表單上的輸入變更時,會呼叫 attachFormChanged 回調函數。 根據表單是否有效,已啟用或停用 [確定] 按鈕。
import * as SDK from "azure-devops-extension-sdk";
SDK.getService(SDK.CommonServiceIds.Dialog).then((dialogService) => {
let registrationForm;
const extensionCtx = SDK.getExtensionContext();
const contributionId = `${extensionCtx.publisherId}.${extensionCtx.extensionId}.registration-form`;
const dialogOptions = {
title: "Registration Form",
width: 800,
height: 600,
getDialogResult: () => {
// Get the result from registrationForm object
return registrationForm ? registrationForm.getFormData() : null;
},
okCallback: (result) => {
// Log the result to the console
console.log(JSON.stringify(result));
}
};
dialogService.openDialog(contributionId, dialogOptions).then((dialog) => {
// Get registrationForm instance which is registered in registration-form.html
dialog.getContributionInstance("registration-form").then((registrationFormInstance) => {
// Keep a reference of registration form instance (to be used previously in dialog options)
registrationForm = registrationFormInstance;
// Subscribe to form input changes and update the Ok enabled state
registrationForm.attachFormChanged((isValid) => {
dialog.updateOkButton(isValid);
});
// Set the initial ok enabled state
registrationForm.isFormValid().then((isValid) => {
dialog.updateOkButton(isValid);
});
});
});
});
控制 [確定] 按鈕
一開始,[確定] 按鈕會停用。 不過,您可以在對話框中呼叫 updateOkButton 方法,以啟用/停用此按鈕:
dialogService.openDialog(contributionId, dialogOptions).then((dialog) => {
// Set true/false to enable/disable ok button
dialog.updateOkButton(true);
});
將值傳遞至對話框
當您在主機對話方塊中開啟對話方塊內容時,可以將初始值傳遞至對話方塊內容。
{
"id": "registration-form",
"type": "ms.vss-web.control",
"description": "The content displayed in the dialog",
"targets": [],
"properties": {
"uri": "registration-form.html?id={{myId}}"
}
}
對話方塊開啟時,必須指定下列選項才能傳遞 myId:
const dialogOptions = {
title: "My Dialog Title",
width: 800,
height: 600,
urlReplacementObject: { myId: new Date().getTime() }
};
自訂對話框按鈕
okText和 cancelText 屬性可用來指定 [確定] 和 [取消] 按鈕的替代標題:
const dialogOptions = {
title: "My Dialog Title",
width: 800,
height: 600,
okText: "Yes",
cancelText: "No"
};
若要不顯示對話方塊上的任何按鈕,您可以將 屬性設定 buttons 為 []:
const dialogOptions = {
title: "My Dialog Title",
width: 800,
height: 600,
buttons: []
};
相關資源
如果您有問題或正在尋找詳細資訊,請考慮前往下列其中一個區域: