为了扩展BPMN.JS的功能,我们通常在Modeler/Viewer实例化时通过传入additionalModules
参数的方法来扩展/修改BPMN-JS的功能。

BPMN-JS通常通过类似下面的代码来自定义DI(依赖注入)模块:
export default class CustomRenderer extends BaseRenderer {
constructor(eventBus, bpmnRenderer) {
super(eventBus, HIGH_PRIORITY);
this.bpmnRenderer = bpmnRenderer;
}
canRender(element) {
return false;
}
drawShape(parentNode, element) {
...
}
getShapePath(shape) {
...
return shape
}
}
CustomRenderer.$inject = ['eventBus', 'bpmnRenderer'];
export default {
__init__: ['CustomRenderer'],
CustomRenderer: ['type', CustomRenderer]
}
上面代码实现了一个继承自BaseRenderer
的CustomRenderer
类,BaseRenderer
类是diagram-js包中实现的一个渲染基类(抽象类),里面定义了一些空的原型方法。通过上面的写法,我们就可以覆盖掉bpmn-js中BaseRenderer
类的实现,从而实现了bpmn-js自定义渲染功能。
另外上面代码CustomRenderer.$inject = ['eventBus', 'bpmnRenderer'];
而这实际上是bpmn.js依赖的diagram-js包所依赖的didi
实现的依赖注入。
didi
是用JavaScript实现的一个依赖注入/控制反转容器。该库对外暴露了如下4个接口
- annotate
- parseAnnotations
- Module
- Injector
annotate
该方法用来将形如['a', 'b', 'c', function(a, b, c) {}]
通用的依赖注入写法,转换为didi
特定的语法:
import { annotate } from "didi";
var fn = annotate(['a', 'b', 'c', function(a, b, c) {}]);
// 或
var fn = annotate('a', 'b', 'c', function(a, b, c) {});
// 输出结果为
var fn = function(a, b, c) {};
fn.$inject = ['a', 'b', 'c'];
parseAnnotations
该方法用来解析JavaScript函数的形参到一个数组,示例:
function Human(name, age) {
this.name = name;
this.age = age;
}
var res = parseAnnotations(Human);
// 结果 ['name', 'age']
Module
这是一个类,didi提供的自定义module接口,示例:
var { Module } = require('didi');
var carModule = new Module();
carModule.type('car', Car).factory('engine', createPetrolEngine).value('power', 1184);
// 或者通过对象字面量的方式来定义didi要注册的module
var carModule = {
'car': ['type', Car],
'engine': ['factory', createPetrolEngine],
'power': ['value', 1184]
};
// 注册到Injector
var injector = new Injector([module]);
Injector
注入器,可以将上面定义的模块,通过一个数组参数实例化进该容器
const injector = new Injector([
carModule
])
// get
injector.get('car').start();
// invoke
injector.invoke(['car', function(car) {
car.start();
}]);
// 根据类的形参,在locals中查找依赖,并在类实例化时将形参依赖进行注入
injector.instantiate(function(a, b, c) {}, locals);
//
injector.createChild(modules, forceNewInstances);
这篇文章目前没有评论