首页 > Vue >

bpmnjs如何自定义Modeler?vue+bpmnjs

时间: 作者:admin 浏览:

项目中使用到bpmnjs的时候,大多数情况都是需要自定义定制才能满足需求,因此bpmnjs的自定义基本不可避免,今天我们来进行vue中的bpmnjs的Modeler自定义过程;

由于bpmnjs自定义过程稍微复杂,刚开始理解起来有些难度,不懂的地方大家耐心多看几遍;

首先自定义要先继承原Modeler,再将需要自定义的模块(CustomModule)与原有模块(modules)合并(或者说覆盖)

import inherits from "inherits";
import Modeler from "bpmn-js/lib/Modeler";
import CustomModule from "../custom/index.js";

function CustomModeler(options) {
    Modeler.call(this, options);
    this._customElements = [];
}

inherits(CustomModeler, Modeler);
CustomModeler.prototype._modules = [].concat(CustomModeler.prototype._modules, [CustomModule]);

export { CustomModeler };

被引用的自定义模块CustomModulecustom/index.js文件(这个文件很重要,以后几乎所有需要自定义引入的模块都在这里import)内容参考如下,假设自定义了左侧工具栏模块:

import paletteProvider from "../customPalette/paletteprovider";
import customPalette from "../customPalette/palette";

export default {
    __init__: [
        "paletteProvider",
        'palette'
    ],
    paletteProvider: ["type", paletteProvider],
    palette: [ 'type', customPalette ],
};

结构目录参考图:

经过以上两步,自定义的CustomModeler对象就出来了,然后将上面的代码整理好放在不同的目录等待引用,下面是CustomModeler的参数设置与使用方法:

<div ref="bpmnbox" class="canvas-box"></div>
import customTranslate from '@/components/bpmnProcess/customTranslate/customTranslate';
import flowableDescriptor from '@/components/bpmnProcess/properties-panel/descriptor/flowable.json';
import flowableMoudle from '@/components/bpmnProcess/properties-panel/extension-moddle/flowable';

export default{
    data(){
        return{

        }
    },
    methods:{
        async getModeler(){
            const { CustomModeler } = await require('@/components/bpmnProcess/customModeler')

            let modeler = await new CustomModeler({
                container: this.$refs.bpmnbox,
                keyboard: {
                    bindTo: window
                },
                height: '100%',
                moddleExtensions: {
                    flowable: flowableDescriptor
                },
                additionalModules: [
                    flowableMoudle, 
                    { //汉化
                        translate: ['value', customTranslate]
                    },
                    {
                        // 禁用滚轮滚动
                        zoomScroll: ["value", ""]
                    }
                ]
            })
            return modeler
        }
    }
}

以上的三个自定义模块customTranslate、flowableDescriptor、flowableMoudle的js文件分别参考如下:

  • customTranslate:汉化模块
    import translations from './translations';
    export default function customTranslate(template, replacements) {
      replacements = replacements || {};
      // Translate
      template = translations[template] || template;
      // Replace
      return template.replace(/{([^}]+)}/g, function(_, key) {
          return translations[replacements[key]] || replacements[key] || '{' + key + '}';
      });
    }
    
    上面的translations参考内容如下(汉化键值对):
    export default {
      'Task': '任务',
      'Process': '流程',
       'UserTask': '用户任务',
      'GateWay': '网关',
      'StartEvent': '开始事件',
      'EndEvent': '结束事件',
    }
    
  • flowableDescriptor:扩展属性相关描述文件
    {
      "name": "Flowable",
      "uri": "http://flowable.org/bpmn",
      "prefix": "flowable",
      "xml": {
          "tagAlias": "lowerCase"
      },
      "associations": [],
      "types": [
      {
          "name": "UserTask",
          "isAbstract": true,
          "extends": [
              "bpmn:UserTask",
              "bpmn:MultiInstanceLoopCharacteristics"
          ],
          "properties": [ {
              "name": "timerEventDefinition",
              "type": "Expression"
              },{
              "name": "multiInstanceLoopCharacteristics",
              "type": "MultiInstanceLoopCharacteristics"
          }]
      },
      {
          "name": "StartEvent",
          "isAbstract": true,
          "extends": [
              "bpmn:StartEvent"
          ],
          "properties": [
              {
                  "name": "timerEventDefinition",
                  "type": "Expression"
              }
          ]
      },
      {
          "name":"Properties",
          "isAbstract": true,
          "extends":[],
          "superClass":["Element"],
          "meta":{
              "allowedIn":["*"]
          },
          "properties":[
          {
              "name":"values",
              "isMany":true,
              "isbody":true,
              "type":"Formright"
          }
          ]
      },
      {
          "name":"Formright",
          "isAbstract": true,
          "extends":[
              "flowable:Exec_before",
              "flowable:Exec_after"
          ],
          "superClass":["Element"],
          "meta":{
              "allowedIn":["*"]
          },
          "properties":[
          {
              "name":"value",
              "isAttr":true,
              "type":"String"
          },
          {
              "name": "body",
              "isBody": true,
              "type": "String"
          }
          ]
      },
      {
          "name": "Property",
          "superClass": [
              "Element"
          ],
          "properties": [
          {
              "name": "id",
              "type": "String",
              "isAttr": true
          },
          {
              "name": "name",
              "type": "String",
              "isAttr": true
          },
          {
              "name": "value",
              "type": "String",
              "isAttr": true
          }
          ]
      }
      ]
    }
    //参考官方仓库:https://github.com/bpmn-io/moddle/blob/master/docs/descriptor.md
    
  • flowableMoudle:扩展属性模块

    module.exports = {
      __init__:["FlowableModdleExtension"],
      FlowableModdleExtension:["type",require("./flowableExtension")]
    }
    

    flowableExtension文件内容参考如下(其实这些文件全都可以在依赖目录找到,只是需要替换成’flowable’):

      "use strict";
      var some = require("min-dash").some;
      var ALLOWED_TYPES = {
          FailedJobRetryTimeCycle: ["bpmn:StartEvent", "bpmn:BoundaryEvent", "bpmn:IntermediateCatchEvent", "bpmn:Activity"],
          Connector: ["bpmn:EndEvent", "bpmn:IntermediateThrowEvent"],
          Field: ["bpmn:EndEvent", "bpmn:IntermediateThrowEvent"]
      };
    
      function is(element, type) {
          return element && typeof element.$instanceOf === "function" && element.$instanceOf(type);
      }
    
      function exists(element) {
          return element && element.length;
      }
    
      function includesType(collection, type) {
          return (
              exists(collection) && some(collection, function(element) {
                  return is(element, type);
              })
          );
      }
    
      function anyType(element, types) {
          return some(types, function(type) {
              return is(element, type);
          });
      }
    
      function isAllowed(propName, propDescriptor, newElement) {
          var name = propDescriptor.name,
              types = ALLOWED_TYPES[name.replace(/flowable:/, "")];
    
          return name === propName && anyType(newElement, types);
      }
    
      function FlowableModdleExtension(eventBus) {
          eventBus.on(
              "property.clone",
              function(context) {
                  var newElement = context.newElement,
                      propDescriptor = context.propertyDescriptor;
                  this.canCloneProperty(newElement, propDescriptor);
              },
              this
          );
      }
    
      FlowableModdleExtension.$inject = ["eventBus"];
    
      FlowableModdleExtension.prototype.canCloneProperty = function(newElement, propDescriptor) {
          if (isAllowed("flowable:FailedJobRetryTimeCycle", propDescriptor, newElement)) {
              return (
                  includesType(newElement.eventDefinitions, "bpmn:TimerEventDefinition") ||
                  includesType(newElement.eventDefinitions, "bpmn:SignalEventDefinition") ||
                  is(newElement.loopCharacteristics, "bpmn:MultiInstanceLoopCharacteristics")
              );
          }
    
          if (isAllowed("flowable:Connector", propDescriptor, newElement)) {
              return includesType(newElement.eventDefinitions, "bpmn:MessageEventDefinition");
          }
    
          if (isAllowed("flowable:Field", propDescriptor, newElement)) {
              return includesType(newElement.eventDefinitions, "bpmn:MessageEventDefinition");
          }
      };
    
      module.exports = FlowableModdleExtension;
    

    使用例子:

    this.modeler = await this.getModeler()
    

    拿到modeler实例以后,怎么获取Modeler各模块?

    this.eventBus = this.modeler.get("eventBus")
    this.modeling = this.modeler.get("modeling")
    this.moddle = this.modeler.get("moddle")
    this.bpmnFactory = this.modeler.get("bpmnFactory")
    this.elementRegistry = this.modeler.get("elementRegistry")
    this.canvas = this.modeler.get("canvas")
    this.selection = this.modeler.get("selection")
    

    到这里,Modeler的自定义以及相关的引用就已经完成了,能看到这里的同学很不错了,可能一开始可能是比较难理解的,只能多看几遍慢慢吸收,接下来的篇章就是分解自定义左侧工具栏、自定义右侧属性栏等等相关的内容,感谢你的耐心阅读。

引导:

关于bpmnjs+vue的更多篇章,小编已经全部整理在这里:
bpmnjs+vue中文文档API常见方法使用总结

微信公众号
微信公众号:
  • 前端全栈之路(微信群)
前端QQ交流群
前端QQ交流群:
  • 794324979
  • 734802480(已满)

更多文章

栏目文章


Copyright © 2014-2023 seozhijia.net 版权所有-粤ICP备13087626号-4