聊一聊bpmn-js中的Palette

bpmn-js中使用Modeler进行流程图的建模,而Palette则是其内部创建的提供左侧工具栏的插件。插件使用didi实现的依赖注入,其创建使用参考上一篇文章:推荐前端一个轻量级别的依赖注入库:didi

Palette实现主要依托三个功能模块:Eventbus(详情参考bpmn-js 事件总线处理)、diagram-jsPalette插件(之后简称Palette)以及bpmn-js中的PaletteProvider(之后简称PaletteProvider)。左侧工具栏的加载原理是:作为Palette的提供方PalettProvider则需要在插件注册之前通过Palette提供的注册器registerProvider注册监听并通过_rebuild会发送一个palette.getProviders事件,将当前提供者添加到Palette的集合中。Palette加载后通过eventbus监听整体页面绘制事件,当页面绘制后Palette将会回调内置_rebuild方法获取小工具栏组件信息,这时候我们的PaletteProvider也已经完成了注册,Palette会通过_rebuild重绘完成整体小工具栏区域的加载。接下来我们了解下bpmn-js中的左侧小工具栏的加载流程。

聊一聊bpmn-js中的Palette

PaletteProvider

可以简单的认为它是最终的提供方,小工具栏上面有什么说到底还是由它决定的。在bpmn-js源码中内置了一个”paletteProvider“,也就是说我们可以什么都不做会有一套默认的小工具栏供我们使用。我们想对其进行修改bpmn-js提供给我们两种方式:完全自定义动态增加。我们先暂时忘掉这两种方式,首先来看下如何去实现一个PaletteProvider的角色)。

注册

想要成为一个PaletteProvider的角色,我们就必须要通过diagram-jspalette的插件进行注册。

// Palette提供者
function PaletteProvider(palette,...){
....
palette
.registerProvider(this);
}

//必须要有diagram-js的palette插件
PaletteProvider.$inject = ['palette']

提供

注册完成后当Palette需要我们绘制的时候我们就需要提供给Palette到底绘制哪些工具?如何绘制?这时候我们需要提供,这里有个核心的方法就是getPaletteEntries,这个方法是Palette获取小工具集合的必须包含的方法,该方法需要我们返回一个对象,对象里可以有多个工具,对象格式姑且以PaletteEntry标识,且所有注册的提供者的集合会被整合。

// 工具对象格式
type
PaletteEntry = {
action
: (event: Event, autoActivate: boolean) => any || {}; // 事件回调,或者是事件对象如{dragStart:()=>{}}
className
?: string; // 类名,这里可用作加载字体图标
group?: string; // 区域划分
html
?: string; // 自定义html显示
imageUrl
?: string; // 图标链接地址
separator
?: boolean;
title
?: string; // 悬停显示文字
};

// 改方法必须有
PaletteProvider.prototype.getPaletteEntries = function() {
return {
'hand-tool': {
group: 'tools',
className
: 'bpmn-icon-hand-tool',
title
: '手型工具',
action
: {
click
: function(event) {
handTool
.activateHand(event);
}
}
},
}
}

上述是手型工具的提供方式,我们常规使用的事件处理也就dragstart、click两种,以下是bpmn-js提供的创建action的方式:

  function createAction(type, group, className, title, options) {

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);
}

return {
group: group,
className
: className,
title
: title,
action
: {
dragstart
: createListener,
click
: createListener
}
};
}

// 上述用到了其他的依赖插件,需要我们在$inject中声明并通过构建函数传入
PaletteProvider.$inject = [
'palette',
'create',
'elementFactory',
'spaceTool',
'lassoTool',
'handTool',
'globalConnect',
'translate'
];

如上createListener提供的是工具的绘制方法,这里使用的bpmn-js提供的几种svg图形绘制,当然若有需要我们也可以自己绘制,这个后续文章会深入讨论。

PaletteProvider既然已经了解完成,这里我们来说下开始的时候说的两种小工具的方式:完全自定义动态增加

  • 完全自定义:将插件名命名为:‘paletteProvider’,会自动覆盖已有的paletteProvider插件。

// 将声明设置为paletteProvider
export default {
__init__
: ['paletteProvider'],
paletteProvider
: ['type', PaletteProvider],
}

// 修改PaletteProvider.js 的getPaletteEntries
// 改方法必须有
PaletteProvider.prototype.getPaletteEntries = function() {
......
return {
'hand-tool': {
group: 'tools',
className
: 'bpmn-icon-hand-tool',
title
: '手型工具',
action
: {
click
: function(event) {
handTool
.activateHand(event);
}
}
},
}
}
聊一聊bpmn-js中的Palette

这样加载后就如上一样只剩一个小小的手型工具了。

  • 动态增加:若只是想加一个新的工具进去,完全可以自定义一个名字,设置号group分区就可以,我们这里还是以上述为例修改下group,需要注意的是工具名需要修改, 不然可能会无效,试试效果:

// 自定义名称
export default {
__init__
: ['customProvider'],
customProvider
: ['type', PaletteProvider],
}

// 修改PaletteProvider.js 的getPaletteEntries
// 改方法必须有
PaletteProvider.prototype.getPaletteEntries = function() {
......
return {
'hand-tool-2': {
group: 'activity',
className
: 'bpmn-icon-hand-tool',
title
: '手型工具2',
action
: {
click
: function(event) {
handTool
.activateHand(event);
}
}
},
}
}
聊一聊bpmn-js中的Palette

这样在activity区域就多了一个手型工具了

Palette

diagram-jsPalette插件可以说是整个bpmn-js的左侧工具的管理模块了,它定义了PaletteProvider的注册方式、提供方法已经工具的类型格式。这里我们来看下几个核心的功能部分。

提供注册

Palette内部实现了一个registerProvider方法来让PaletteProvider进行注册登记,并通知Palette构建组件信息,通过eventbus方式将其加载到内部的event


// 注册实现
Palette.prototype.registerProvider = function(priority, provider) {

...
// 添加监听将provider加载到内部的event中
this._eventBus.on('palette.getProviders', priority, function(event) {
event.providers.push(provider);
});

this._rebuild();
};

// 组件构建部分
Palette.prototype._rebuild = function() {
// 这里用于发送信息让注册方法的监听添加provider
var providers = this._getProviders();
...
this._update();
};

// 这里是发送获取组件的消息
Palette.prototype._getProviders = function(id) {
var event = this._eventBus.createEvent({
type
: 'palette.getProviders',
providers
: []
});
this._eventBus.fire(event);
return event.providers;
};

监听绘制

Palette插件开始加载的时候会监听diagram-js的绘制事件,并在合适的时机重写加载绘制组件:

export default function Palette(eventBus, canvas) {



......
// toolMananger插件用于协助管理palette组件的编辑状态
eventBus
.on('tool-manager.update', function(event) {
var tool = event.tool;
self.updateToolHighlight(tool);
});

// 国际化监听
eventBus
.on('i18n.changed', function() {
self._update();
});

// diagram初始化监听
eventBus
.on('diagram.init', function() {
self._diagramInitialized = true;
self._rebuild();
});
}

如上就是本篇文章的所有的内容了,若是感兴趣或是觉得对你有所帮助,欢迎关注一直在前端路上陪伴你的胖蔡~


原文始发于微信公众号(胖蔡话前端):聊一聊bpmn-js中的Palette

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/222918.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!