在前端开发中,我们常常需要使用 BPMN 语言来描述各种业务流程,同时也需要通过活动、用户任务和网关等元素来描述流程中的各个阶段和执行步骤。npm 包 bpmn-js-properties-panel-activiti-support 就是在此背景下产生的一款基于 bpmn-js 的 npm 包,它提供了一些支持 Activiti 自定义扩展属性的面板,使我们能够在 BPMN 编辑器中方便地添加和编辑各种扩展属性。在本篇文章中,我们将详细介绍如何使用该 npm 包进行前端开发。
使用 npm 安装 bpmn-js-properties-panel-activiti-support
在开始使用 bpmn-js-properties-panel-activiti-support 前,我们需要保证已经安装好了 node.js 和 npm,如果没有安装,请先安装好。
使用 npm 安装 bpmn-js-properties-panel-activiti-support 只需要执行以下命令即可:
npm install bpmn-js-properties-panel-activiti-support
安装完成后,我们可以在 package.json 文件中看到已经添加了该包的依赖信息:
{ "dependencies": { "bpmn-js-properties-panel-activiti-support": "^0.3.0" } }
在前端项目中使用 bpmn-js-properties-panel-activiti-support
安装完成后,我们需要在前端项目中引用该包并进行相关配置。
导入 bpmn-js-properties-panel-activiti-support
在需要使用 bpmn-js-properties-panel-activiti-support 的文件中,我们需要先引入该包:
import PropertiesPanelActivitiSupportModule from 'bpmn-js-properties-panel-activiti-support'; // 引入 bpmn-js 的主组件 import BpmnModeler from 'bpmn-js/lib/Modeler'; // 同时也需要引用 bower_components 中的 jquery、lodash 和 bpmn-js-properties-panel
扩展 bpmn-js 的面板配置
接着,我们需要在 bpmn-js 的配置中添加该包的配置信息,以便在编辑器中显示该扩展面板,具体需要配置的信息有如下几个部分:
1. module.imports
在 module.imports 中需要引入 bpmn-js-properties-panel 和 bpmn-js-properties-panel-activiti-support,同时也需要在该变量定义中添加 bpmnjs.properties-panel 和 bpmnjs.properties-panel-activiti-support 的别名,以便在后面的配置中使用。
let customTranslate = { //... }; let additionalModules = [ PropertiesPanelActivitiSupportModule ]; let bpmnModeler = new BpmnModeler({ //... additionalModules, moddleExtensions: { //... }, // 定义别名 propertiesPanel: { parent: '#js-properties-panel', // 别名配置 additionalModules: [ { // bpmn-js-properties-panel 的别名 module: 'properties-panel', // bpmn-js-properties-panel 的路径 path: 'bpmn-js-properties-panel/dist', // 配置相对路径时添加的路径前缀,用于区分相对于 bpmn-js-properties-panel 或项目目录的路径 absolutePathPrefix: '../node_modules' }, { // bpmn-js-properties-panel-activiti-support 的别名 module: 'properties-panel-activiti-support', // bpmn-js-properties-panel-activiti-support 的路径 path: 'bpmn-js-properties-panel-activiti-support/dist', absolutePathPrefix: '../node_modules' } ], // 属性面板的配置信息 propertiesProvider: { //... }, //... }, //... }
2. propertiesProvider
在 propertiesProvider 中定义每个元素的扩展属性面板信息,包括每个元素的 ID、elementName、provider 和 descriptor 等属性,设置这些属性后,我们就可以在编辑面板中显示出扩展属性面板,默认情况下不显示。
let customTranslate = { //... }; let additionalModules = [ PropertiesPanelActivitiSupportModule ]; let bpmnModeler = new BpmnModeler({ //... additionalModules, moddleExtensions: { //... }, //... propertiesPanel: { parent: '#js-properties-panel', additionalModules: [ //... ], // 使用 propertiesPanel-activiti-support propertiesProvider: { // 给模型添加一个默认属性和活动 'bpmn:Process': { properties: [ { // 当前选中元素的 id id: 'test', // 当前选中元素的名称 name: '测试', // 接受提供者对象,向其提供数据 provider: { // 选项 entries: [ // 选项对象 { id: 'test-text', label: '测试属性', // 定义要绑定到此属性的值 modelProperty: 'test', // 绑定的 HTML 元素类型 html: { // 设置属性类型为 input 的文本 type: 'input', // 设置输入框的占位符 placeholder: '测试属性', // 将输入框的值绑定到模型数据 binding: { name: 'test', type: 'property', expression: '${test}' } } } ] } } ] }, //... }, //... }, //... })
在编辑中使用扩展属性面板
在完成以上配置后,我们即可在 bpmn-js 编辑中使用扩展属性面板。
例如,在某个元素上右键单击,弹出弹出菜单后,单击 “Edit” 可以看到显示了新添加的属性面板。
// ... // 右键菜单 $('#js-drop-zone').contextmenu(function(event) { if (canContain(event.target)) { currentTarget = event.target; openPopup('properties-panel'); } return false; }); //... /** * 弹出属性面板 * @param String id 绑定 html 元素 id */ function openPopup(id) { $('#' + id).show(); var popup = $('#' + id).data('ui-dialog'); if (!popup) { $('#' + id).dialog({ title: translate('PropertiesPanel'), //... }); } else { popup.open(); } }
完整示例代码
下面是一个完整的示例,包括了 BpmnModeler 的配置和添加事件:
import jQuery from 'jquery'; import BpmnModeler from 'bpmn-js/lib/Modeler'; import PropertiesPanelModule from 'bpmn-js-properties-panel'; import PropertiesPanelActivitiSupportModule from 'bpmn-js-properties-panel-activiti-support'; import Lrud from 'lrud'; import { debounce } from 'lodash'; window.jQuery = jQuery; const container = document.getElementById('canvas'); const propertiesPanelContainer = document.getElementById('js-properties-panel'); // bpmn-js config const additionalModules = [ PropertiesPanelModule, PropertiesPanelActivitiSupportModule ]; // bpmn-js module configuration const customTranslate = { 'Properties': '自定义属性', 'General': '基本属性', 'Details': '详细信息', 'Variables': '变量', 'Documentation': '文档', 'Executable': '执行标记', 'Tasklist': '任务列表', 'CallActivity': '外部任务' }; // ... 其他自定义翻译 const DEFAULT_XML = '<?xml version="1.0" encoding="UTF-8" standalone="no"?><bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="Definitions_1" targetNamespace="http://bpmn.io/schema/bpmn"><bpmn:process id="Process_1" isExecutable="false"><bpmn:startEvent id="StartEvent_1"/></bpmn:process><bpmndi:BPMNDiagram id="BPMNDiagram_1"><bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1"><bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1"><dc:Bounds x="173" y="102" width="36" height="36"/></bpmndi:BPMNShape></bpmndi:BPMNPlane></bpmndi:BPMNDiagram></bpmn:definitions>'; const supportTransitionEvents = ['element.scroll', 'element.click']; const modeler = new BpmnModeler({ container: container, propertiesPanel: { // 可选url或html准备好. parent: '#js-properties-panel', additionalModules: [ PropertiesPanelActivitiSupportModule ], propertiesProvider: { 'custom:p': { label: 'Process', properties: [ { id: 'test', name: '测试', description: '测试属性', groups: ['testGroup'], html: { type: 'input', binding: { name: 'test', type: 'property', expression: '${test}' } } } ] }, bpmn: { label: 'BPMN', properties: [ { id: 'process-name', description: 'Set the name of the process', label: 'Process Name', type: 'String', value: 'My Process', editable: true, binding: { type: 'property', name: 'name', expression: '${value}' } } ] }, activiti: { label: 'Activiti', properties: [ { id: 'process-id', label: 'Process Id', type: 'String', value: '', group: 'process-details', description: 'The subprocess id', editable: true, binding: { type: 'property', name: 'activiti:processId', expression: '${value}' } }, { id: 'execution-listener', label: 'Execution listener', type: 'Combo', description: 'execution listener', group: 'process-details', editable: true, binding: { type: 'property', name: 'activiti:executionListener', expression: '${value}' }, selectOptions: [ { name: 'Java class', value: 'class' }, { name: 'Expression', value: 'expression' }, { name: 'Delegate expression', value: 'delegateExpression' } ] } ] } } }, additionalModules: [ Lrud ], moddleExtensions: { // ... }, // 其他配置信息 // ... }); // ... function bindSupportTransitionEvents(modeler, events, fn, context) { const throttledFn = debounce(fn, 100); events.forEach(function(event) { modeler.get('eventBus').on(event, function() { const args = [].slice.call(arguments); // we're only interested in the first // argument, the modeling or renderer fn.apply(context, [args[0]]); }); }); } bindSupportTransitionEvents( modeler, supportTransitionEvents, function(target) { saveXML(function(err, xml) { if (xml) { console.log('[XML]', xml); } }); } ); function saveXML(done) { modeler.saveXML({ format: true }, function(err, xml) { done(err, xml); }); } function createNewDiagram() { openDiagram(DEFAULT_XML); } function openDiagram(xml) { modeler.importXML(xml, function(err) { if (err) { console.error(err); } else { console.log(DEFAULT_XML); } }); } function onKeyDown(e) { if (isCmd(e) && e.keyCode === 83 /* + S */) { saveXML(function(err, xml) { if (err) { console.error('failed to save xml', err); } else { console.info('xml saved'); } }); e.stopPropagation(); e.preventDefault(); } } document.addEventListener('keydown', onKeyDown); document.addEventListener('DOMContentLoaded', function() { createNewDiagram(); });
总结
本文主要介绍了如何使用 npm 包 bpmn-js-properties-panel-activiti-support 进行前端开发,并通过详细的示例代码展示了如何在 BpmnModeler 中添加扩展面板配置,同时也提供了关于该 npm 包使用的深度指导意义。相信读者在学习过程中已经掌握了该 npm 包的使用方法,能够在实际开发中灵活使用该 npm 包。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/600673dffb81d47349e53c40