上一篇文章里我们了解了bpmn-js
使用palette
模块进行左侧小工具区域(也可以理解为调色板区域)的功能扩展,今天这个话题则是延续上期的palette
进行开展的。

从上篇文章《聊一聊bpmn-js中的Palette》我们知道,PaletteProvider
通过getPaletteEntries
方法提供小工具Map
对象,而单个小工具绘制对象格式如下:
type PaletteEntry = {
action: (event: Event, autoActivate: boolean) => any || {}; // 事件回调,或者是事件对象如{dragStart:()=>{}}
className?: string; // 类名,这里可用作加载字体图标
group?: string; // 区域划分
html?: string; // 自定义html显示
imageUrl?: string; // 图标链接地址
separator?: boolean;
title?: string; // 悬停显示文字
};
这里action
作为palette
与主建模编辑的交互模块,palette
中引用了elementFactory
和create
模块进行绘制创建和管理。而本篇文章我们的主角就是工具的元素创建工具类:ElementFactory
,其插件模块位于diagram-js/lib/core/ElementFactory.js
,在PaletteProvider
中的使用如下:
// 声明注入模块
PaletteProvider.$inject = [
......
'create',
'elementFactory',
......
];
// 初始化
export default function PaletteProvider(...,create, elementFactory,...){
......
this._create = create;
this._elementFactory = elementFactory;
......
}
PaletteProvider.prototype.getPaletteEntries = function() {
function createAction(type, group, className, title, options){
// 事件交互创建shape
function createListener(event) {
var shape = elementFactory.createShape(assign({ type: type }, options));
if (options) {
var di = getDi(shape);
di.isExpanded = options.isExpanded;
}
create.start(event, shape);
}
}
......
}
上述可以发现,元素的绘制包括两个模块:elementFactory
、create
。create
主要是处理触发事件后的动作操作,elementFactory
用于创建当前元素,本篇文章主要来介绍diagram-js
中的elementFactory
模块。
元素类型
elementFactory
是diagram-js
中用于提供创建元素模型的一个工厂类,主要还是以创建元素模型为主(即元素结构,元素绘制由单独的defaultRenderer
模块负责)。在elementFactory
模块中将元素的模型分为四类,当且仅当绘制的类型是这四类才能成功创建,否则将会抛出异常:unknown type
。
elementFactory
的元素类型通过一个变量来定义控制,这也是为了便于扩展,日后由其他新增的类型也不是没有可能的,且所有类型都是基于基础类型ElementImpl的基础上进行的扩展,我们可以通过代码了解:
var types = {
connection: ConnectionImpl,
shape: ShapeImpl,
label: LabelImpl,
root: RootImpl
};
// 基础类型
function ElementImpl() {
Object.defineProperty(this, 'businessObject', {
writable: true
});
Object.defineProperty(this, 'label', {
get: function() {
return this.labels[0];
},
set: function(newLabel) {
var label = this.label,
labels = this.labels;
if (!newLabel && label) {
labels.remove(label);
} else {
labels.add(newLabel, 0);
}
}
});
// 实现关联元素的双向引用
parentRefs.bind(this, 'parent');
labelRefs.bind(this, 'labels');
outgoingRefs.bind(this, 'outgoing');
incomingRefs.bind(this, 'incoming');
}
通过上述代码可以发现ElementImpl
给所有元素定义了一些基础实现和绑定:
-
businessObject
:这是元素的属性信息汇总对象 -
label
:支持单标签,将映射到多标签阵列 -
绑定:
ElmenetImpl
实现了元素的父类、流入、流出、多标签绑定
elementFactory
中的所有绑定关系将会交由elementFactory
模块内部统一维护:
var parentRefs = new Refs({ name: 'children', enumerable: true, collection: true }, { name: 'parent' }),
labelRefs = new Refs({ name: 'labels', enumerable: true, collection: true }, { name: 'labelTarget' }),
attacherRefs = new Refs({ name: 'attachers', collection: true }, { name: 'host' }),
outgoingRefs = new Refs({ name: 'outgoing', collection: true }, { name: 'source' }),
incomingRefs = new Refs({ name: 'incoming', collection: true }, { name: 'target' });
1、connection
connection
元素就是连接线用于将两个元素进行连接,其中主要包含定义元素来源和元素流入的方向绑定:
function ConnectionImpl() {
ElementImpl.call(this);
// 来源于
outgoingRefs.bind(this, 'source');
// 流向
incomingRefs.bind(this, 'target');
}
// 创建示例
import * as Model from 'diagram-js/lib/model';
const connection = Model.create('connection', {
waypoints: [
{ x: 100, y: 100 },
{ x: 200, y: 100 }
]
});
2、shape
shape
类型主要就是用于创建有形状的元素,类似开始、流程、判断等工作流元素。
function ShapeImpl() {
ElementImpl.call(this);
// 绑定子元素
parentRefs.bind(this, 'children');
attacherRefs.bind(this, 'host');
attacherRefs.bind(this, 'attachers');
}
// 创建示例
import * as Model from 'diagram-js/lib/model';
const shape = Model.create('shape', {
x: 100,
y: 100,
width: 100,
height: 100
});
3、label
label
类型主要是给其他元素提供文字管理,它继承于一个shape
类型,而非基础的element
类型。
function LabelImpl() {
ShapeImpl.call(this);
labelRefs.bind(this, 'labelTarget');
}
// 示例创建
import * as Model from 'diagram-js/lib/model';
const label = Model.create('label', {
x: 100,
y: 100,
width: 100,
height: 100,
labelTarget: shape
});
4、root
这里就是当前bpmn-js
流程图的根节点了,也就是bpmn:process
元素,更节点包含的元素较为简单主要是存在与所有子元素的关联:
function RootImpl() {
ElementImpl.call(this);
parentRefs.bind(this, 'children');
}
// 示例创建
import * as Model from 'diagram-js/lib/model';
const root = Model.create('root', {
x: 100,
y: 100,
width: 100,
height: 100
});
工厂方法
elementFactory
提供的工厂方法比较直球,基本你看到方法名称就知道它是创建什么元素的:
-
createRoot
:创建root
元素 -
createLabel
:创建label
-
createShape
:创建带有形状的元素 -
createConnection
:创建连接线 -
create
:这是所有工厂方法的实现
原文始发于微信公众号(胖蔡话前端):聊一聊bpmn-js中的elementFactory模块
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/222913.html