zoukankan      html  css  js  c++  java
  • vue项目中使用bpmn-节点篇(为节点添加点击事件、根据id找节点实例、更新节点名字、获取指定类型的所有节点)

    内容概述

    本系列 “vue项目中使用bpmn-xxxx” 分为七篇,均为自己使用过程中用到的实例,手工原创,目前陆续更新中。主要包括vue项目中bpmn使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。如果转载或通过爬虫直接爬的,格式特别丑,请来原创看:我是作者原文

    前情提要

    根据之前的操作,我们可以创建、导入、导出流程图,并对其进预览。通过此篇可以学到:

    • 为节点添加点击、鼠标悬浮等事件
    • 获取流程图内所有指定类型的节点
    • 通过外部更新节点名字
    • 获取节点实例的两种方法,根据节点id拿到元素实例

    来看一眼效果图

    step1:为节点添加点击、鼠标悬浮等事件

    方案:bpmnModeler中的eventBus,只要你要,只要它有

    代码:

    const eventBus = this.bpmnModeler.get('eventBus');
    // 注册节点事件,eventTypes中可以写多个事件
    const eventTypes = ['element.click', 'element.hover'];
    eventTypes.forEach((eventType) => {
      eventBus.on(eventType, (e) => {
        const {element} = e;
        if (!element.parent) return;
        if (!e || element.type === 'bpmn:Process') {
          return false;
        } else {
          if (eventType === 'element.click') {
            // 节点点击后想要做的处理
            // 此时想要点击节点后,拿到节点实例,通过外部输入更新节点名称
            this.currentElement = element;
          } else if (eventType === 'element.hover') {
            // 鼠标滑过节点后想要做的处理
            console.log('鼠标经过节点啦~');
          }
        }
      });
    });
    View Code

    step2:获取流程图内所有指定类型的节点

    场景:需要获取流程图里所有的用户节点信息,以列表形式展示在另外地方。查了很多文档,并没有找到。事实证明,源码才是王道!  

    方案:elementRegistry提供了方案,并且支持过滤

    代码:

    const elementRegistry = this.bpmnModeler.get('elementRegistry');
    const userTaskList = elementRegistry.filter(
      (item) => item.type === 'bpmn:UserTask'
    );

    step3 : 通过外部更新节点名字

    方案:bpmnModeler的modeling,提供了updateLabel方法,modeling.updateLabel(节点id,新名字);

    step4: 获取节点实例的两种方法  

    4.1 通过step1中的点击事件等,可以直接拿到目标对象e,e.element就是节点实例

    eventBus.on('element.click', (e) => {console.log(e.element);})

    4.2  没有任何事件可以触发,手里空空只有一个节点id

      方案:bpmnModeler的elementRegistry来解围!

    const elementRegistry = this.bpmnModeler.get('elementRegistry');
    console.log(elementRegistry.get(节点id));

    后续

    上文代码都是片段,特此附上完整代码:老规矩:data中的chart变量流程图xml文件数据,由于行数过多,附在了附件中(点我!点我),使用时,将附件内容复制过来,赋值给chart即可运行!

    <template>
        <div class="containerBox">
            <div style="margin-left: 250px">
                通过输入框更改节点名称:
                <el-input
                        v-model.trim="nodeName"
                        placeholder="请输入节点名称"
                        clearable
                        @input="inputChange"
                        style=" 200px">
                </el-input>
            </div>
            <div id="container"></div>
        </div>
    </template>
    <script>
        import BpmnModeler from 'bpmn-js/lib/Modeler';
        import camundaExtension from './resources/camunda';
        import {tempDetail, saveCanvas} from '@api/processConfig';
    
        export default {
            name: 'index',
            data() {
                return {
                    containerEl: null,
                    bpmnModeler: null,
                    currentElement: {},
                    nodeName: "",
                    // chart变量流程图xml文件数据,由于行数过多,附在了附件中,使用时,将附件整个赋值给chart即可
                    chart: '<bpmn:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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:camunda="http://camunda.org/schema/1.0/bpmn" 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:outgoing>Flow_021z3si</bpmn:outgoing>
    ' +
                        '</bpmn:startEvent>
    ' +
                        '<bpmn:serviceTask id="Activity_1fru9kc" name="我是第一个节点">
    ' +
                        '<bpmn:incoming>Flow_021z3si</bpmn:incoming>
    ' +
                        '<bpmn:outgoing>Flow_1hwj8kv</bpmn:outgoing>
    ' +
                        '</bpmn:serviceTask>
    ' +
                        '<bpmn:sequenceFlow id="Flow_021z3si" sourceRef="StartEvent_1" targetRef="Activity_1fru9kc"> </bpmn:sequenceFlow>
    ' +
                        '<bpmn:userTask id="Activity_0ozmm5p" name="第二名">
    ' +
                        '<bpmn:incoming>Flow_1hwj8kv</bpmn:incoming>
    ' +
                        '<bpmn:outgoing>Flow_1tbnntc</bpmn:outgoing>
    ' +
                        '</bpmn:userTask>
    ' +
                        '<bpmn:sequenceFlow id="Flow_1hwj8kv" sourceRef="Activity_1fru9kc" targetRef="Activity_0ozmm5p"> </bpmn:sequenceFlow>
    ' +
                        '<bpmn:sequenceFlow id="Flow_1tbnntc" sourceRef="Activity_0ozmm5p" targetRef="Event_03kmy6i"> </bpmn:sequenceFlow>
    ' +
                        '<bpmn:endEvent id="Event_03kmy6i">
    ' +
                        '<bpmn:incoming>Flow_1tbnntc</bpmn:incoming>
    ' +
                        '</bpmn:endEvent>
    ' +
                        '</bpmn:process>
    ' +
                        '<bpmndi:BPMNDiagram id="BPMNDiagram_1">
    ' +
                        '<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1">
    ' +
                        '<bpmndi:BPMNEdge id="Flow_021z3si_di" bpmnElement="Flow_021z3si">
    ' +
                        '<di:waypoint x="209" y="120"/>
    ' +
                        '<di:waypoint x="290" y="120"/>
    ' +
                        '</bpmndi:BPMNEdge>
    ' +
                        '<bpmndi:BPMNEdge id="Flow_1hwj8kv_di" bpmnElement="Flow_1hwj8kv">
    ' +
                        '<di:waypoint x="390" y="120"/>
    ' +
                        '<di:waypoint x="480" y="120"/>
    ' +
                        '</bpmndi:BPMNEdge>
    ' +
                        '<bpmndi:BPMNEdge id="Flow_1tbnntc_di" bpmnElement="Flow_1tbnntc">
    ' +
                        '<di:waypoint x="580" y="120"/>
    ' +
                        '<di:waypoint x="672" y="120"/>
    ' +
                        '</bpmndi:BPMNEdge>
    ' +
                        '<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
    ' +
                        '<dc:Bounds x="173" y="102" width="36" height="36"/>
    ' +
                        '</bpmndi:BPMNShape>
    ' +
                        '<bpmndi:BPMNShape id="Activity_1fru9kc_di" bpmnElement="Activity_1fru9kc">
    ' +
                        '<dc:Bounds x="290" y="80" width="100" height="80"/>
    ' +
                        '</bpmndi:BPMNShape>
    ' +
                        '<bpmndi:BPMNShape id="Activity_0ozmm5p_di" bpmnElement="Activity_0ozmm5p">
    ' +
                        '<dc:Bounds x="480" y="80" width="100" height="80"/>
    ' +
                        '</bpmndi:BPMNShape>
    ' +
                        '<bpmndi:BPMNShape id="Event_03kmy6i_di" bpmnElement="Event_03kmy6i">
    ' +
                        '<dc:Bounds x="672" y="102" width="36" height="36"/>
    ' +
                        '</bpmndi:BPMNShape>
    ' +
                        '<bpmndi:BPMNShape id="Activity_0lkkmka_di">
    ' +
                        '<dc:Bounds x="820" y="80" width="100" height="80"/>
    ' +
                        '</bpmndi:BPMNShape>
    ' +
                        '<bpmndi:BPMNEdge id="Flow_1t2mucq_di">
    ' +
                        '<di:waypoint x="920" y="120"/>
    ' +
                        '<di:waypoint x="1012" y="120"/>
    ' +
                        '</bpmndi:BPMNEdge>
    ' +
                        '</bpmndi:BPMNPlane>
    ' +
                        '</bpmndi:BPMNDiagram>
    ' +
                        '</bpmn:definitions>'
                };
            },
            mounted() {
                this.containerEl = document.getElementById('container');
                this.bpmnModeler = new BpmnModeler({
                    container: this.containerEl,
                    moddleExtensions: {camunda: camundaExtension}
                });
                this.showChart();
            },
            methods: {
                getShapeById() {
                    const elementRegistry = this.bpmnModeler.get('elementRegistry');
                    console.log(elementRegistry.get('Activity_0ozmm5p'));
                },
                inputChange(val) {
                    const modeling = this.bpmnModeler.get('modeling');
                    if (JSON.stringify(this.currentElement) === '{}') {
                        this.$message.info('请保证要更改的节点处于选中状态!');
                        return false;
                    } else {
                        modeling.updateLabel(this.currentElement, val);
                    }
                },
                // 流程图回显
                showChart() {
                    this.bpmnModeler.importXML(this.chart, (err) => {
                        if (!err) {
                            this.addEventBusListener();
                            this.getNodeInfoList();
                            this.getShapeById();
                        }
                    });
                },
                // 获取流程图中所有节点信息
                getNodeInfoList() {
                    const elementRegistry = this.bpmnModeler.get('elementRegistry');
                    const userTaskList = elementRegistry.filter(
                        (item) => item.type === 'bpmn:UserTask'
                    );
                    // 此时得到的userTaskList 便是流程图中所有的用户节点的集合
                    console.log(userTaskList);
                },
                addEventBusListener() {
                    const eventBus = this.bpmnModeler.get('eventBus');
                    // 注册节点事件,eventTypes中可以写多个事件
                    const eventTypes = ['element.click', 'element.hover'];
                    eventTypes.forEach((eventType) => {
                        eventBus.on(eventType, (e) => {
                            const {element} = e;
                            if (!element.parent) return;
                            if (!e || element.type === 'bpmn:Process') {
                                return false;
                            } else {
                                if (eventType === 'element.click') {
                                    // 节点点击后想要做的处理
                                    // 此时想要点击节点后,拿到节点实例,通过外部输入更新节点名称
                                    this.currentElement = element;
                                } else if (eventType === 'element.hover') {
                                    // 鼠标滑过节点后想要做的处理
                                    console.log('鼠标经过节点啦~');
                                }
                            }
                        });
                    });
                }
            }
        };
    </script>
    <style lang="scss">
        .containerBox {
            height: calc(100vh - 220px);
            position: relative;
    
            #container {
                height: calc(100% - 50px);
            }
        }
    </style>
    View Code

     想获取完整源码或有问题,欢迎大家关注我的公粽号,扫下面二维码或微信搜“前端便利贴”,即可获取~

    可爱的你可能还需要

  • 相关阅读:
    FastDFS--storage文件上传和下载问题
    Ubuntu18.04中安装virtualenv和virtualenvwrapper
    详解文件包含漏洞
    pikachu-数字型注入-sqlmap
    sqlmap命令手册
    SQL注入详解及技巧
    Linux中更新firefox
    DVWA-SQL注入
    CTF杂项题解题思路
    ubuntu搭建环境
  • 原文地址:https://www.cnblogs.com/lemoncool/p/12746217.html
Copyright © 2011-2022 走看看