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
相关推荐
Bryce李小白4 小时前
Kotlin Flow 的使用
android·开发语言·kotlin
洛卡卡了4 小时前
Sentry 都不想接,这锅还让我背?这xx工作我不要了!
前端·架构
咖啡の猫4 小时前
Vue 实例生命周期
前端·vue.js·okhttp
JNU freshman4 小时前
vue 之 import 的语法
前端·javascript·vue.js
剑亦未配妥4 小时前
Vue 2 响应式系统常见问题与解决方案(包含_demo以下划线开头命名的变量导致响应式丢失问题)
前端·javascript·vue.js
爱吃的强哥4 小时前
Vue2 封装二维码弹窗组件
javascript·vue.js
凉柚ˇ4 小时前
Vue图片压缩方案
前端·javascript·vue.js
慧一居士4 小时前
vue 中 directive 作用,使用场景和使用示例
前端
jarreyer4 小时前
python离线包安装方法总结
开发语言·python
慧一居士4 小时前
vue 中 file-saver 功能介绍,使用场景,使用示例
前端