Bpmn.js详细入门,创建节点,删除节点(章节二)

news/2024/10/18 12:19:27/

前言
首先这玩意没有一个标准的中文官方文档,英文的也没有,英文只有一个官方的各种案例,所以需要学习全面,还是得去官网的案例里面找
因为我在学这个的时候,网上搜到的很多信息都已经很老了,导致组件在使用过程中很多写法不对,甚至引入路径都找不到,所以我还是决定写一个相对新一点的,这里就给大家入个门,讲一些基本使用,以及我个人在过程中遇到的东西,希望能帮到你

这里是官网案例链接

https://github.com/bpmn-io/bpmn-js-examples

在前面的章节一里面已经讲解了如何初始化、导入和下载功能,接下来看看如何创建和删除节点

创建节点

我们事先在初始化成功的函数里获取到需要用到的方法,不知道这个从哪里来的可以进主页看章节一

	success() {console.log('创建成功!')this.modeling = this.bpmnModeler.get("modeling")this.elementRegistry = this.bpmnModeler.get('elementRegistry');this.elementFactory = this.bpmnModeler.get("elementFactory");},

这里我用封装的方式,因为在我的业务场景里面只需要用代码来创建Task、UserTask和TextAnnotation这三种类型,所以我的对他们的坐标处理也只有这些,具体可以根据你自己的需要来

	//startShape表示在谁的后面创建节点//type创建类型createTaskShape(startShape, type) {const shapTask = type || 'Task'//获取根节点const rootElement = this.bpmnModeler.get('canvas').getRootElement()let branchShape = this.elementFactory.createShape({type: "bpmn:" + shapTask,})var shapeX, shapeYif (branchShape.type === startShape.type) {shapeX = branchShape.width * 2shapeY = branchShape.height / 2} else {switch (shapTask) {case 'UserTask':shapeX = 150// 为了对齐,用task节点的高减去start节点高的一半,后面减去4是边框的pxshapeY = (branchShape.height - startShape.height) / 2 - 4break;case 'Task':shapeX = 150shapeY = (branchShape.height - startShape.height) / 2 - 4break;case 'TextAnnotation':shapeX = 90shapeY = 150break;default:break;}}//branchShape要创建的节点//坐标位置//rootElement表示在根节点创建return this.modeling.createShape(branchShape,{x: startShape.x + shapeX,y: startShape.y + shapeY},rootElement)},

创建完之后,还需要做一件事,就是将他们连接在一起,当然如果不需要就不用管
更改节点属性的方法也在里面

//先获取前面的节点
const startShape = this.elementRegistry.get(shape.id);
//然后创建
const taskShape = this.createTaskShape(startShape, 'Task')
//然后使用modeling来改变他们为自己想要的属性
this.modeling.updateProperties(taskShape, {id: id,name: name,documentation: [documentation]
})
// documentation元素在businessObject里,所以无法直接更改,需要创建一个新的documentation
// 不明白的可以打印taskShape看一下元素信息
const bpmnFactory = this.bpmnModeler.get("bpmnFactory")
const documentation = bpmnFactory.create("bpmn:Dcumentation",{ text:"text" })
// 连接
this.modeling.connect(startShape, taskShape)

删除节点

删除就简单多了,直接获取canvas,然后执行方法

const Canvas = this.bpmnModeler.get("canvas")
Canvas.removeShape(shape.id)

那么做了这么多,怎么执行这个创建删除呢?
首先创建节点监听事件

  • 当新增、移动、删除模型时
	modelerListerner() {// 监听modelerconst that = this// 'shape.removed','connect.end','connect.move'const event = ['shape.added', 'shape.move.end', 'shape.removed']event.forEach(function (event) {that.bpmnModeler.on(event, e => {if (event === 'shape.added') {console.log('新增了shape');}} else if (event === 'shape.move.end') {console.log('移动了shape');} else if (event === 'shape.removed') {console.log('删除了shape');}})})},
  • 对模型进行操作时
EventBusListener() {const eventBus = this.bpmnModeler.get('eventBus')// 这里还有更多操作事件,需要了解的可以在操作完shape之后打印eventTypesconst eventTypes = ['element.click', 'element.changed', 'element.hover', 'element.out']const that = this// 判断是否为无效值let isInvalid = (param) => {return param === null || param === undefined || param === ''}// 判断是否为线let isSequenceFlow = (type) => {return type === 'bpmn:SequenceFlow'}let getShape = (id) => {return that.elementRegistry.get(id)}let elementChanged = (e) => {var shape = getShape(e.element.id)if (!shape) {// 若是shape为null则表示珊瑚,无论是shape还是connect删除都调用此处console.log('无效的shape');// 上面已经用shape.removed 检测了shape的删除,如果删除shape这里还会被触发一次console.log('删除了shape和connect');return}if (!isInvalid(shape.type)) {if (isSequenceFlow(shape.type)) {console.log('改变了线');}}}eventTypes.forEach(function (eventTypes) {eventBus.on(eventTypes, function (e) {var shape = e.element ? that.elementRegistry.get(e.element.id) : e.shapeif (!e || e.element.type == 'bpmn:Process') returnif (eventTypes === 'element.changed') {console.log('改变了element', e);elementChanged(e)} else if (eventTypes === 'element.click') {console.log('点击了element', shape);if (shape.type === 'bpmn:StartEvent') {console.log('开始事件');}} else if (eventTypes === 'element.hover') {console.log('鼠标移入');}} else if (eventTypes === 'element.out') {console.log('鼠标移出');}})})},

当然,关于bpmn的任何事件都需要在最后写在初始化成功之后的函数里

 	success() {console.log('创建成功!')this.modeling = this.bpmnModeler.get("modeling")this.elementRegistry = this.bpmnModeler.get('elementRegistry');this.elementFactory = this.bpmnModeler.get("elementFactory");this.modelerListerner()this.EventBusListener()},

http://www.ppmy.cn/news/733529.html

相关文章

【32单片机学习】(5)STM32响应优先级和抢占优先级

两个中断同时到来,谁的响应优先级高,谁先被触发; 响应优先级相同时看硬件优先级序号,即响应优先级(软件优先级)高于硬件优先级; 抢占优先级可以打断当前中断,相当于比响应优先级更…

【STM32单片机学习】(12)数码管动态扫描(联合体结构体)超简单

数码管动态扫描采用联合体union关键字和结构体组合,使用定时器中断刷新,在此分享和记录一下。 文章目录 前言一、pandas是什么?二、使用步骤 1.引入库2.读入数据总结 一、union关键字 union,中文名“联合体、共用体”,…

【32单片机学习】(10)STM32串口+内部温度传感器+光敏传感器通过DMA搬运数据

目录 前言 一、DMA及各外设介绍 二、实验现象 串口发送 LCD显示 三、代码部分 1.adc部分 adc.c adc.h 2.串口部分 serial.c serial.h 3.DMA配置 dma.c dma.h 4.main函数 main.c 总结 前言 基于stm32f103zet6,将串口收发不定长数据和adc采集通过使…

RGB环形补光灯行业头部企业市场占有率及排名调研报告

本文调研和分析全球RGB环形补光灯发展现状及未来趋势,核心内容如下: (1)全球市场总体规模,分别按销量和按收入进行了统计分析,历史数据2018-2022年,预测数据2023至2029年。 (2&#…

【51单片机学习】(1):单片机入门

1.C51数据类型 在C51中int只占两个字节 2.RAM和ROM ROM:(Read Only Memory) 程序存储器在单片机中用来存储程序数据及常量数据或变量数据,凡是c文件及h文件中所有代码、全局变量、局部变量、const’限定符定义的常量数据、startup.asm文件中的代码(类…

【32单片机学习】(1)stm32位带操作

位带区操作 STM32F10x支持位带操作的两个内存区的范围是: 0x2000_0000-0x200F_FFFF(SRAM 区中的最低 1MB) 0x4000_0000-0x400F_FFFF(片上外设区中的最低 1MB) 例如操作GPIOB5->ODR寄存器(GPIOB_ODR寄…

【32单片机学习】(2)stm32库文件

startup_stm32f10x_hd.s 设置堆栈指针、设置PC指针、初始化中断向量表、配置系统时钟、调用C库函数_main,将汇编环境转到C语言编译环境 ; Reset handler //程序从此处开始 Reset_Handler PROCEXPORT Reset_Handler [WEAK]IMPORT __mainIMPORT S…

【51单片机学习】(2)定时器扫描实现按键长按和短按

用Delay消抖时会导致主程序中的一些进程受到影响&#xff0c;所以在这里借鉴江科大使用定时器扫描按键状态进行消抖的方法。在实际使用中加入了长按功能 按键驱动代码key.c #include <REGX52.H>unsigned char Key_KeyNumber,KeyTime,KeyCount,i; unsigned int times;/**…