手机网站模板带后台,企业简介介绍,接项目做的网站,深圳外贸seo网站推广接上文bpmnjs Properties-panel拓展#xff08;属性设置篇#xff09;#xff0c;继续记录下第三个拓展需求的实现。
需求简述
在ExclusiveGateway标签的extensionElements标签中增加子标签activiti:executionListener子标签#xff0c;可增加复数子标签。子标签…接上文bpmnjs Properties-panel拓展属性设置篇继续记录下第三个拓展需求的实现。
需求简述
在ExclusiveGateway标签的extensionElements标签中增加子标签activiti:executionListener子标签可增加复数子标签。子标签中包含event属性和delegateExpression属性可进行设置并实现name属性的自动生成。event属性默认设为start。 那么最终的结构可表示为
- exclusiveGateway- extensionElements- activiti:exectionListener event, name, delegateExpressionjson属性设置
在activiti.json中增加要拓展的属性 {name: executionListener,superClass: [ Element ],isMany: true,properties: [{name: event,isAttr:true,type: String},{name: delegateExpression,isAttr: true,type: String}]}补充executionListener的具体定义主要的是superClass设为Element这样会被归到extensionElements里。
ExtensionExecutionListener组件
用来构建单条的executionListener。 ExtensionExecutionListener.js
import { TextFieldEntry } from bpmn-io/properties-panel;import { useService } from bpmn-js-properties-panel;// 构建list中的一层包括event设置和delegateExpression设置
export default function ExtensionExecutionListener(props) {const {idPrefix,element,executionListener} props;const entries [{// idPrefix是外部传进来的element id所以增加一个后缀来进行区分id: idPrefix -event,component: event,idPrefix,executionListener},{id: idPrefix -delegateExpression,component: delegateExpression,idPrefix,executionListener}];return entries;
}// 设置event属性
function event(props) {// 要注意的是executionListener需要它来进行属性的修改 const {idPrefix,element,executionListener} props;const commandStack useService(commandStack);const translate useService(translate);const debounce useService(debounceInput);const setValue (value) {commandStack.execute(element.updateModdleProperties, {element,moddleElement: executionListener,properties: {event: value}});};const getValue (executionListener) {return executionListener.event;};// 也可使用html拼接return TextFieldEntry({element: executionListener,id: idPrefix -event,label: translate(event),getValue,setValue,debounce});
}// 设置delegateExpression属性
function delegateExpression(props) {const {idPrefix,element,executionListener} props;const commandStack useService(commandStack);const translate useService(translate);const debounce useService(debounceInput);const setValue (value) {commandStack.execute(element.updateModdleProperties, {element,moddleElement: executionListener,properties: {delegateExpression: value}});};// exectionListener获取属性const getValue (executionListener) {return executionListener.delegateExpression;};// 也可使用html拼接return TextFieldEntry({element: executionListener,id: idPrefix -delegateExpression,label: translate(delegateExpression),getValue,setValue,debounce});
}主要是构建了包含event和delegateExpression的entries。需要注意的是和前文bpmnjs Properties-panel拓展属性设置篇中不同这里使用了commandStack命令栈去直接执行update这种方法后面也会用到好处是能将数个指令存到array中一起执行比较方便写不过错误提示会变成一坨可能是我用的不对吧。
ExtensionExecutionListenerGroup
需要在ExtensionElements中塞进多个ExecutionListener因此需要构建其组成的list。
import {getBusinessObject
} from bpmn-js/lib/util/ModelUtil;import { without } from min-dash;
import ExtensionExecutionListener from ./ExtensionExecutionListener;import Ids from ids;function nextId(prefix) {const ids new Ids([32, 32, 1]);return ids.nextPrefixed(prefix);
}function createElement(elementType, properties, parent, factory) {const element factory.create(elementType, properties);if (parent) {element.$parent parent;}return element;
}首先是几个工具方法getId随机构建不重复的id信息createElement方法利用bpmnFactory来构建bpmnElement是一种bpmnjs定义的结构体用于后续插入整体的xml中。
// 获取element的extensionElment下的所有ExecutionListener
function getExtensionExecutionListeners(element) {const businessObject getBusinessObject(element);// 不存在就算了if (!businessObject.extensionElements) {return null;}// 存在则使用filter找出所有的activiti:exectionListenerreturn businessObject.extensionElements.values.filter(function (e) {return e.$instanceOf(activiti:executionListener);});
}工具方法找executionListener。executionListener是在extensionElement下的所以从那里利用filter找返回是一个array或空。
// 关键方法构建listener list
export default function ExtensionExecutionListenerGroup({ element, injector }) {// 防空const executionListeners getExtensionExecutionListeners(element) || [];console.log(executionListeners);const bpmnFactory injector.get(bpmnFactory),commandStack injector.get(commandStack);// 对list中的每个item进行构建const items executionListeners.map((executionListener, index) {// 按顺序给个idconst id element.id -executionListener- index;// 构建itemreturn {id,label: executionListener.get(event) --- executionListener.get(delegateExpression) || ,entries: ExtensionExecutionListener({idPrefix: id,element,executionListener}),autoFocusEntry: id -el,remove: removeFactory({ commandStack, element, executionListener })};});return {items,add: addFactory({ element, bpmnFactory, commandStack })};
}主要是进行组件的构建。需要注意的是设置remove方法和add方法分别是在可视化界面中进行组件增加和删除时调用的方法。
// 去除item时执行的方法先获取extensionElement之后进行without处理最后更新
function removeFactory({ commandStack, element, executionListener }) {return function (event) {event.stopPropagation();const executionListeners getExtensionExecutionListeners(element);if (!executionListeners) {return;}const businessObject getBusinessObject(element);// 利用without将当前item对应的信息剔除console.log(executionListeners);const executionListenersAfter without(executionListeners, executionListener);console.log(executionListenersAfter);// 更新剔除后的信息commandStack.execute(element.updateModdleProperties, {element,moddleElement: businessObject.get(extensionElements),properties: {values: executionListenersAfter}});};
}remove中主要工作就是先找到所有executionListener组成的array之后通过without方法去除要删除的对象最后进行update。
// 增加item时执行的方法
function addFactory({ element, bpmnFactory, commandStack }) {return function (event) {event.stopPropagation();// 存放处理命令最后使用commandStack执行const commands [];const businessObject getBusinessObject(element);let extensionElements businessObject.get(extensionElements);// extensionElements是bpmn自带的属性不存在则先创建if (!extensionElements) {extensionElements createElement(bpmn:ExtensionElements,{ values: [] },businessObject,bpmnFactory);commands.push({cmd: element.updateModdleProperties,context: {element,moddleElement: businessObject,properties: { extensionElements }}});}// 构建exectionListenerconst newExecutionListener createElement(activiti:executionListener, {name: nextId(ExecutionListener_),event: start, // 这边其实可以改成下拉框delegateExpression: }, extensionElements, bpmnFactory);// 增加至extensionElementscommands.push({cmd: element.updateModdleProperties,context: {element,moddleElement: extensionElements,properties: {// 使新增的显示在下面values: [newExecutionListener, ...extensionElements.get(values)]}}});commandStack.execute(properties-panel.multi-command-executor, commands);};
}增加item主要分为三步新增extensionElements构建executionListener并给出随机idupdate。
注册到可视化面板
在ActivitiPropertiesProvider.js中将组件进行注册 // 网关增加extensionElementExecutionListenerif(is(element, bpmn:ExclusiveGateway)){groups.push(createExtensionExclusiveGateway(element, injector, translate));}// 构建extensionElement下的exectionListener
function createExtensionExclusiveGateway(element, injector, translate){// 构建group listconst elGroup {id: ExtensionExectionListener,label: translate(对应监听实现类设置),component: ListGroup,...ExtensionExecutionListenerGroup({ element, injector })};return elGroup;
}实现效果 list增删成员 xml成功修改
总结
实现了增加ExtensionElements中标签成员的需求其实实现逻辑还是比较清晰的构建组件组件list注册三步走。不过写的时候还是踩了不少坑调了蛮久还得多练啊。项目已上传至Github https://github.com/huiluczP/huiluczp-activiti-properties-panel-extension感兴趣可以看一下。