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

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

    可爱的你可能还需要

  • 相关阅读:
    在C#代码中应用Log4Net(二)典型的使用方式
    在C#代码中应用Log4Net(一)简单使用Log4Net
    Windows Azure Active Directory (2) Windows Azure AD基础
    Windows Azure Virtual Network (6) 设置Azure Virtual Machine固定公网IP (Virtual IP Address, VIP) (1)
    Windows Azure Active Directory (1) 前言
    Azure China (6) SAP 应用在华登陆 Windows Azure 公有云
    Microsoft Azure News(3) Azure新的基本实例上线 (Basic Virtual Machine)
    Microsoft Azure News(2) 在Microsoft Azure上运行SAP应用程序
    Microsoft Azure News(1) 新的数据中心Japan East, Japan West and Brazil South
    Windows Azure HandBook (2) Azure China提供的服务
  • 原文地址:https://www.cnblogs.com/lemoncool/p/12746217.html
Copyright © 2011-2022 走看看