赞
踩
contextPad
就是元素追加的上下文,可以直接在画板上的元素上添加其他元素。
在前面我们自定义了palette
和render
模块后,左侧工具栏和画板上的元素已经变成自定义的样式,但是contextPad
这部分还没有变化。同样这里也需要重写contextPad
的方法来覆盖默认方法。
在plugins
文件目录下新建context-pad
文件夹。创建一个index.js
入口文件和contextPadProvider.js
自定义contextPad
文件(用来覆盖默认contextPad)。
import { assign, forEach, isArray } from "min-dash"; import { is } from "bpmn-js/lib/util/ModelUtil"; import { isAny } from "bpmn-js/lib/features/modeling/util/ModelingUtil"; import { hasPrimaryModifier } from "diagram-js/lib/util/Mouse"; export default function ContextPadProvider( config, injector, eventBus, contextPad, modeling, elementFactory, connect, create, popupMenu, canvas, rules, translate, elementRegistry ) { config = config || {}; contextPad.registerProvider(this); this._contextPad = contextPad; this._modeling = modeling; this._elementFactory = elementFactory; this._connect = connect; this._create = create; this._popupMenu = popupMenu; this._canvas = canvas; this._rules = rules; this._translate = translate; if (config.autoPlace !== false) { this._autoPlace = injector.get("autoPlace", false); } eventBus.on("create.end", 250, function (event) { var context = event.context, shape = context.shape; if (!hasPrimaryModifier(event) || !contextPad.isOpen(shape)) { return; } var entries = contextPad.getEntries(shape); if (entries.replace) { entries.replace.action.click(event, shape); } }); } ContextPadProvider.$inject = [ "config.contextPad", "injector", "eventBus", "contextPad", "modeling", "elementFactory", "connect", "create", "popupMenu", "canvas", "rules", "translate", "elementRegistry" ]; ContextPadProvider.prototype.getContextPadEntries = function (element) { var contextPad = this._contextPad, modeling = this._modeling, elementFactory = this._elementFactory, connect = this._connect, create = this._create, popupMenu = this._popupMenu, canvas = this._canvas, rules = this._rules, autoPlace = this._autoPlace, translate = this._translate; var actions = {}; if (element.type === "label") { return actions; } var businessObject = element.businessObject; function startConnect(event, element) { connect.start(event, element); } function removeElement() { modeling.removeElements([element]); } /** * Create an append action * * @param {string} type * @param {string} className * @param {string} [title] * @param {Object} [options] * @return {Object} descriptor */ function appendAction(type, className, title, options) { if (typeof title !== "string") { options = title; title = translate("Append {type}", { type: type.replace(/^bpmn:/, "") }); } function appendStart(event, element) { var shape = elementFactory.createShape(assign({ type: type }, options)); create.start(event, shape, { source: element }); } var append = autoPlace ? function (event, element) { var shape = elementFactory.createShape(assign({ type: type }, options)); autoPlace.append(element, shape); } : appendStart; return { group: "model", className, title, action: { dragstart: appendStart, click: append } }; } if (is(businessObject, "bpmn:FlowNode")) { if ( !is(businessObject, "bpmn:EndEvent") ) { assign(actions, { "append.append-task": appendAction("bpmn:UserTask", "icon-custom taskNode", translate("Append Task")), "append.gateway": appendAction("bpmn:ExclusiveGateway", "icon-custom gatewayNode", translate("Append Gateway")), "append.end-event": appendAction("bpmn:EndEvent", "icon-custom endNode", translate("Append EndEvent")), }); } } if (isAny(businessObject, ["bpmn:FlowNode", "bpmn:InteractionNode", "bpmn:DataObjectReference", "bpmn:DataStoreReference"])) { assign(actions, { connect: { group: "edit", // className: "bpmn-icon-connection-multi", className: "feelec feel-lianxian", title: translate("Connect using " + (businessObject.isForCompensation ? "" : "Sequence/MessageFlow or ") + "Association"), action: { click: startConnect, dragstart: startConnect } } }); } // delete element entry, only show if allowed by rules var deleteAllowed = rules.allowed("elements.delete", { elements: [element] }); if (isArray(deleteAllowed)) { // was the element returned as a deletion candidate? deleteAllowed = deleteAllowed[0] === element; } if (deleteAllowed) { assign(actions, { delete: { group: "edit", className: "bpmn-icon-trash", title: translate("Remove"), action: { click: removeElement } } }); } return actions; };
代码思路解析:
重写 ContextPadProvider
类,同时覆盖了其原型上的 getContextPadEntries
方法
getContextPadEntries
方法返回一个对象,和 PaletteProvider
一样,返回的是需要的元素。
不同的是 contextPad
通过判断元素的类型来决定追加哪些元素。比如在结束节点 EndEvent
就没有其他元素,只有一个删除节点,而其他节点一样,所以就需要在 EndEvent
这个节点单独判断。
import CustomContextPadProvider from "./contextPadProvider";
export default {
__init__: ["contextPadProvider"],
contextPadProvider: ["type", CustomContextPadProvider]
};
自定义样式文件process-panel.scss
里再加入样式 contextPad 原生hover样式。
.djs-context-pad{ & .startNode.entry:hover { background: url('../../../../../../public/bpmn_imgs/startNode.png') center no-repeat !important; background-size: cover !important; } & .endNode.entry:hover { background: url('../../../../../../public/bpmn_imgs/endNode.png') center no-repeat !important; background-size: cover !important; } & .taskNode.entry:hover { background: url('../../../../../../public/bpmn_imgs/taskNode.png') center no-repeat !important; background-size: cover !important; } & .gatewayNode.entry:hover { background: url('../../../../../../public/bpmn_imgs/gatewayNode.png') center no-repeat !important; background-size: cover !important; } & .entry { box-sizing: border-box; background-size: 100%; transition: all 0.3s; } & .entry:hover { border: 1px solid #1890ff; } }
到这里需要自定义样式的这三部分就完成了,最后的使用就在初始化BpmnModeler
时添加这三个自定义模块。
customBpmn.vue
文件
<template> <div> <div ref="bpmn-canvas"> </div> </template> <script> import BpmnModeler from "bpmn-js/lib/Modeler"; // 自定义左侧菜单(修改 默认任务 为 用户任务) import CustomPaletteProvider from "../package/process-designer/plugins/palette"; // 自定义渲染 import CustomRenderer from "../package/process-designer/plugins/render"; // 自定义元素选中时的弹出菜单(修改 默认任务 为 用户任务) import CustomContextPadProvider from "../package/process-designer/plugins/context-pad"; export default { data() { return { bpmnModeler: null, }; }, mounted() { this.initBpmnModeler(); }, methods: { initBpmnModeler() { if (this.bpmnModeler) return; this.bpmnModeler = new BpmnModeler({ container: this.$refs.bpmn - canvas, additionalModules: [ CustomPaletteProvider, CustomRenderer, CustomContextPadProvider, ], //添加自定义模块 }); }, }, }; </script>
最后这三部分都变成自定义的样式了,要修改样式或者逻辑就在对应的文件修改,灰常Nice!!!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。