Azure DevOps Services |Azure DevOps Server |Azure DevOps Server 2022 |Azure DevOps Server 2020
模式对话提供了一种在 Azure DevOps 扩展中创建重点用户体验的强大方法。 通过对话框服务,可以呈现一个模式对话框,该对话会阻止用户与整个 Azure DevOps 界面的交互,直到对话框被消除。 此作可确保用户完成重要任务或提供所需的信息。
在扩展中使用模式对话框可以:
- 通过表单收集用户输入
- 显示关键操作的确认信息
- 显示需要用户注意的详细信息
- 指导用户完成多步骤过程
重要
创建模式对话时,它们会阻止与整个 Azure DevOps 页的交互,而不仅仅是扩展。 此方法提供真正的模式体验,但你应该深思熟虑地使用它,以避免中断用户工作流。
先决条件
| 类别 | 要求 | 详细信息 |
|---|---|---|
| 扩展设置 | 正在进行的扩展项目 | 有效的 vss-extension.json 清单文件 |
| 市场注册 | 注册到 Visual Studio Marketplace 进行测试和部署的扩展 | |
| 开发知识 | 了解 Azure DevOps 扩展开发基础知识 | |
| 开发环境 | Node.js 和 npm | 安装有 npm 的 Node.js 版本 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 调用返回非 null 值,则此值将传递给 (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: []
};
相关资源
如果你有疑问或正在寻找更多信息,请考虑转到以下方面之一: