cmmnjs的前端实践:3、添加辅助元素

80 阅读2分钟

在前端开发中,cmmnjs模型和bpmnjs模型有许多类似可参照的地方,本文聚焦于cmmnjs的使用,与bpmn中类似的点将不做赘述。主要说明cmmn和bpmn的不同之处和节点的相关操作。

示例:项目地址 ,基于vue实现,但cmmnjs相关逻辑与框架无关,可直接迁移至其它框架。

代码中涉及到功能模块的部分,将直接以对应模块名称代替,实际开发时需要通过cmmnModeler.get('模块名')获取。

一、辅助元素

辅助元素是指在不会出现在画布上,对节点补充描述或定义执行规则的元素。 在cmmn中,对节点更新属性使用modeling.updateProperties方法,更新辅助元素使用modeling.updateControls方法。 以下说明一些常见的辅助元素。

二、documentation文档节点

文档节点是节点的附加信息,对流程执行无影响。可通过以下方式添加

// 通过text指定内容
const exp = cmmnFactory.create('cmmn:Documentation', {
    text: '111'
});

let documentation = shape.businessObject.definitionRef.documentation || [];
documentation.push(exp);
modeling.updateControls(shape, {
    documentation,
});

对应的xml文件表现为

<cmmn:planItem id="PlanItem_1eavv6s" definitionRef="HumanTask_1b7x2ml" />
<cmmn:humanTask id="HumanTask_1b7x2ml">
    <cmmn:documentation id="Documentation_0gsnhox">111</cmmn:documentation>
</cmmn:humanTask>

如上,文档节点会出现在节点定义中。一个节点定义可以包含多个文档节点,通过 shape.businessObject.definitionRef.documentation 获取

三、控制节点

控制节点一般用于定义节点执行时的规则或逻辑,在使用不同执行规则时需要添加不同的控制节点,一般通过cmmnFactory.create方法创建。常见的比如规定某节点需要手动激活时,需要添加ManualActivationRule节点。

  const exp = cmmnFactory.create("cmmn:ManualActivationRule");
  modeling.updateControls(shape, {
    manualActivationRule: exp,
  });

或是指定一些特殊节点中的表达式。

  // 指定子案例节点中的子案例id
  const target = elementRegistry.get("CasePlanModel_1");
  const ele = elementFactory.createPlanItemShape("cmmn:CaseTask");
  modeling.createShape(ele, { x: 650, y: 300 }, target);
  // 通过body指定表达式内容
  const exp = cmmnFactory.create("cmmn:Expression", {
    body: `<![CDATA[子案例id]]>`,
  });
  modeling.updateControls(ele, {
    caseRefExpression: exp,
  });

  // 指定时间监听器中的时间表达式
  const target = elementRegistry.get("CasePlanModel_1");
  const ele = elementFactory.createPlanItemShape("cmmn:TimerEventListener");
  modeling.createShape(ele, { x: 650, y: 300 }, target);
  const exp = cmmnFactory.create("cmmn:Expression", {
    body: `<![CDATA[${new Date().toISOString()}]]>`,
  });
  modeling.updateControls(ele, {
    timerExpression: exp,
  });

表达式中的CDATA是xml中的一种特殊语法,会将其中的内容视为纯文本,避免内容被解析或转义。 不同规则会使用不同的控制节点不同,但创建方式类似,具体添加进哪个属性中需按规则确定。

四、自定义扩展元素

配合特定执行引擎(比如camunda、flowable)时,可以在cmmn中使用扩展元素增加功能。 要添加自定义扩展元素,需要先写对应的描述文件,在初始化时添加进moddleExtensions中。描述文件的结构与bpmn基本相同,可参照bpmn的相关文章,如 bpmn描述文件说明

写好描述文件后,在初始化时指定。

  cmmnModeler = new CmmnModeler({
    container: container.value,
    moddleExtensions: {
      flowable: flowableModdleDescriptor,
    },
  });

就可以通过moddle.create方法创建扩展元素,并添加进对应节点的extensionElements中。

  // 获取原有的扩展元素
  let extensionElements = shape.businessObject?.definitionRef?.extensionElements;
  // 创建扩展元素并配置描述文件中定义好的属性
  const exp = moddle.create("flowable:TaskListener", {
    event: "create",
    delegateExpression: "${nodeService}",
  });
  // 原有的扩展元素存在则添加 不存在则创建
  if (extensionElements) {
    extensionElements.get("values").push(exp);
  } else {
    extensionElements = moddle.create("cmmn:ExtensionElements", { values: [] });
    // 通过values属性添加扩展元素
    extensionElements.values.push(exp);
  }
  // 更新
  modeling.updateControls(shape, {
    extensionElements: extensionElements,
  });