需求背景:
在以bpmn.js为框架基础的流程编辑器开发中,遇到一个需求,需要获取与开始节点直连的用户任务节点。如果是单任务简单流程,直连的用户任务节点只有一个。如果遇到了复杂的网关,可能有多个用户任务节点。
分析
首先以一个简单流程为例,只有一个开始节点,结束节点,一个用户任务节点,两条连接线
我们打印出流程中所有节点,观察一下数据。
modeler.get("elementFactory") //获取所有节点
可以看到,用户任务节点里,有一个incoming和outgoing。incoming里是进来的连接线,outgoing是出来的连接线。同理,我们找到开始节点对应的出去的连接线,是这一条
我们找到开始节点出来的这条线,对应的节点,观察数据
可以看到开始节点出来的这条线,节点属性里有一个target,target里放得就是这条线要通向的节点,也就是用户任务1.
那么思路就清晰了,要找到开始节点直连了哪些用户任务节点,找到从开始节点的出来的那条线的target,就能找到对应的用户任务节点。
如果遇到网关也不用怕,比如这种
判断开始节点出来的连接线的target的类型,是不是usertask,如果是网关类型,找网关节点的outgoing,看里面有几条线,再在每条线里找对应的target,就能得到要的用户任务节点。
贴一下代码
代码我们写的时候有封装,大家看懂原理,对应在项目里就知道怎么改了。
const getFirstTasks = () => {
console.log(BpmnHelper.getModeler().get('elementRegistry'),"所有标签")
let firstTasksList:any = [];
//开始节点的出线
const firstFlow = BpmnHelper.getModeler().get('elementRegistry').find(function (item) {
return item.type == "bpmn:StartEvent";
})?.outgoing[0];
if(firstFlow && firstFlow.target && firstFlow.target.type == 'bpmn:UserTask') {
firstTasksList.push(firstFlow.target)
}else{
//开始节点连接网关
firstFlow.target?.outgoing.forEach(ele => {
firstTasksList.push(ele.target)
});
}
return firstTasksList;
}