bpmn-js 事件总线处理

bpmn-js中使用EventBus作为事件的处理句柄,EventBus的使用和我们常规使用的事件总线没啥大的区别,其源码位于:/diagram-js/lib/core/EventBus.js bpmn-js使用diagram-js实现流程图的web端绘制呈现工具)。

EventBus使用

事件总线使用基本都是以监听、回调的方式来实现的。diagram-js提供的EventBus也不无例外。如下为EventBus使用方式。

1、添加监听事件

diagram-js提供的EventBus在监听方式上提供了几种不同的选择,如下,可根据需要选择不同的监听方式:

  • 普通监听

  • 带参监听

  • 返回值监听

  • 优先级监听

  • 上下文监听

    • // listen for event
    • eventBus.on('foo', function(event) {
    • // access event type
    • event.type; // 'foo'
    • // stop propagation to other listeners
    • event.stopPropagation();
    • // prevent event default
    • event.preventDefault();
    • });
    • // listen for event with custom payload
    • eventBus.on('bar', function(event, payload) {
    • console.log(payload);
    • });
    • // listen for event returning value
    • eventBus.on('foobar', function(event) {
    • // stop event propagation + prevent default
    • return false;
    • // stop event propagation + return custom result
    • return {
    • 复制代码
      complex: 'listening result'
    • };
    • });
    • // listen with custom priority (default=1000, higher is better)
    • eventBus.on('priorityfoo', 1500, function(event) {
    • console.log('invoked first!');
    • });
    • // listen for event and pass the context (this)
    • eventBus.on('foobar', function(event) {
    • this.foo();
    • }, this);

2、发送事件

EventBus通过fire来发送事件,发送事件可配合上述不同类型监听实现。

复制代码
 *
 * // false indicates that the default action
 * // was prevented by listeners
 * if (eventBus.fire('foo') === false) {
 *   console.log('default has been prevented!');
 * };
 *
 *
 * // custom args + return value listener
 * eventBus.on('sum', function(event, a, b) {
 *   return a + b;
 * });
 *
 * // you can pass custom arguments + retrieve result values.
 * var sum = eventBus.fire('sum', 1, 2);
 * console.log(sum); // 3

3、其他操作

  • off:移除监听回调,若回调函数为空,则移除该监听的所有回调
  • createEvent: 创建一个可被EventBus识别的事件
  • once:注册一个只能被监听一次的事件

如何使用eventbus?

我们可以通过bpmn-js获取的viewer/modeler对象在diagram-js加载完成后添加事件监听。通过bpmn-js提供的eventbus来进行事件监听可以帮助我们给流程编辑器添加钩子和流程图交互配置,如通过监听事件适当添加配置属性。

1、使用viewer进行监听

viewer可以在加载完成diagram-js加载完成后通过viewer.get('eventBus')获取eventbus

复制代码
var viewer = new BpmnJS({ container: bpmnContainer});

try {
    await viewer.importXML(diagramXM); // 此处异步操作完成后可进行事件操作

    var eventBus = viewer.get('eventBus');

    // you may hook into any of the following events
    var events = [
      'element.hover',
      'element.out',
      'element.click',
      'element.dblclick',
      'element.mousedown',
      'element.mouseup'
    ];

    events.forEach(function(event) {

  
      eventBus.on(event, function(e) {
        // e.element = the model element
        // e.gfx = the graphical element

        log(event, 'on', e.element.id);
      });
   });


} catch (err) {
	console.error('Error happened: ', err);
}

可以通过off来取消监听,但需要改变下写法:

复制代码
var viewer = new BpmnJS({ container: bpmnContainer});

try {
    await viewer.importXML(diagramXM); // 此处异步操作完成后可进行事件操作

    var eventBus = viewer.get('eventBus');

    function ensureHoveringProcess(event) {
      event.element = rootElement;
      event.gfx = rootElementGfx;
    }
  eventBus.on('element.hover', ensureHoveringProcess)
  // 监听之后
   eventBus.off('element.hover', ensureHoveringProcess);
// 或者如下取消所有element.hover的监听
  eventBus.off('element.hover')


} catch (err) {
	console.error('Error happened: ', err);
}

2、使用Modeler进行监听

modeler可以直接使用modeler对象进行监听和取消监听操作,而无需额外获取:

复制代码
modeler.on('commandStack.changed', () => {
  // user modeled something or
  // performed an undo/redo operation
});

modeler.on('element.changed', (event) => {
  const element = event.element;

  // the element was changed by the user
});

3、依赖注入

bpmn-js提供给我们足够大的自定义空间,通过在modeler/viewer中的additionalModules配置让我们可以进行各类插件的自定义改装操作,可参照Bpmn-js自定义Palette

复制代码
const bpmnModeler = new BpmnModeler({
        container: this.$refs["bpmn-canvas"],
        additionalModules: [],

});

而自定义的additionalModules通过使用$inject属性来声明依赖注入的各个模块。如此我们也可以通过这种方式创建一个单独进行logger记录的插件:

复制代码
 // logger插件
  function InteractionLogger(eventBus) {
    eventBus.on('element.hover', function(event) {
      console.log()
   })
 }
 
 InteractionLogger.$inject = [ 'eventBus' ]; // 注入插件模块
 
  // 插件模块声明
 var extensionModule = {
   __init__: [ 'interactionLogger' ],
  interactionLogger: [ 'type', InteractionLogger ]
};

// viewer加载
var bpmnViewer = new Viewer({
  container:viewerContainer, 
  additionalModules: [ extensionModule ] 
});
// modeler加载
var bpmnModeler = new BpmnModeler({
  container:viewerContainer, 
  additionalModules: [ extensionModule ] 
})

我们也可以通过自定义元素shape、palette时注入eventbus,添加我们自己的事件监听。

内置事件

通过diagram-js实现的元素绘制、布局相应的其会在内部内置元素的各类事件以提供我们调试,跟踪事件以及其他额外元素操作使用,在使用bpmn-js较为常见的事件监听如下:

1、元素事件类

复制代码
element.changed,
element.out,
element.hover,
element.updateId,
element.marker.update,
bpmnElement.added

2、copyPaste类

复制代码
moddleCopy.canCopyProperties,
moddleCopy.canSetCopiedProperty,
copyPaste.canCopyElements,
copyPaste.elementsCopied,
copyPaste.pasteElements,
copyPaste.pasteElement,
copyPaste.createTree,
copyPaste.copyElement

3、contextPad类

复制代码
contextPad.trigger,
contextPad.open,
contextPad.create,
contextPad.close

4、render类

复制代码
canvas.viewbox.changing,
canvas.init,
canvas.viewbox.changed,
canvas.resized,
render.shape,
render.getShapePath,
render.connection,
render.getConnectionPath,
canvas.destroy,
diagram.init,
diagram.destroy,
diagram.clear

5、connect类

复制代码
connection.added,
connection.removed,
connect.ended,
connect.canceled
相关推荐
陈随易1 分钟前
Lodash 杀手来了!es-toolkit v1.39.0 已完全兼容4年未更新的 Lodash
前端·后端·程序员
potender9 分钟前
前端基础学习html+css+js
前端·css·学习·html·js
追风赶月、11 分钟前
【QT】认识QT
开发语言·qt
Hilaku17 分钟前
你以为的 Tailwind 并不高效,看看这些使用误区
前端·css·前端框架
帅夫帅夫19 分钟前
Vibe Coding从零开始教你打造一个WebLLM页面
前端·人工智能
Vonalien20 分钟前
Trae 深度体验:从怀疑到真香,AI 如何重塑我的开发流?
前端
刘白Live21 分钟前
【html】localStorage设置和获取局部存储的值
前端
白瓷梅子汤21 分钟前
跟着官方示例学习 @tanStack-table --- Basic
前端·react.js
openInula前端开源社区21 分钟前
【openInula茶话会】第三期:Vue转换到openInula技术揭秘
前端·javascript
哄哄57522 分钟前
Antd中Upload组件封装及使用:
前端