Closed bevishwang closed 3 years ago
好问题,我过两天看看
@hbh3819 你好,我尝试了一下,不适用devtools修改配置是正常的,window下对应的数据也会修改。
问题最初是在这样的场景中出现的:自定义的组件中使用了MyProcessDesigner组件,并针对其value绑定了一个动态属性,然后使用http请求获取服务端的xml,在http响应后修改MyProcessDesigner的value绑定的动态属性为请求的返回值,此时可能由于http请求是在MyProcessDesigner初始化完成后才响应的,引起了重新初始化,于是就会不时出现组件间属性不一致的情况。
经测试当把http请求的延迟控制在较大的范围时:比如1s,组件之间属性不一致的情况会稳定复现
您可以使用如下代码来模拟当http请求出现较大延迟时的效果,在App.vue的created生命周期函数中添加:
setTimeout(() => { let newValue = '<?xml version="1.0" encoding="UTF-8"?>\n' + '<bpmn2:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn2="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" id="diagram_Process_1618884876252" targetNamespace="http://bpmn.io/schema/bpmn" xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd">\n' + ' <bpmn2:process id="Process_1618884876252" name="修改名称后的业务流程_1618884876252" isExecutable="true" />\n' + ' <bpmndi:BPMNDiagram id="BPMNDiagram_1">\n' + ' <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1618884876252" />\n' + ' </bpmndi:BPMNDiagram>\n' + '</bpmn2:definitions>'; this.$set(this.controlForm, 'value', newValue) }, 1000);
你这个问题我大致清楚了,因为当初为了减少开销,本身 process-designer.vue 是没有监听 value 变化的。不然会导致一点小变动这边都会重新绘制流程图。 你可以在 请求 完成之后,重新调用 createNewDiagram(xml) 方法来主动刷新流程图
我看到process-designer.vue中的watch已经包含了针对value属性监听,并在其发生变化时重新绘制流程图呢
watch: { value: { handler: function(val) { this.createNewDiagram(val); } } }
问题似乎出现PropertiesPanel.vue中的getActiveElement方法中:
getActiveElement() { // 初始第一个选中元素 bpmn:Process this.processElement = window.bpmnInstances.elementRegistry.find(el => el.type === "bpmn:Process"); this.initFormOnChanged(this.processElement); // 监听选择事件,修改当前激活的元素以及表单 this.bpmnModeler.on("selection.changed", ({ newSelection }) => { if (newSelection && newSelection.length) { const element = newSelection[0]; this.initFormOnChanged(element); } else { this.initFormOnChanged(this.processElement); } }); this.bpmnModeler.on("element.changed", ({ element }) => { // 保证 修改 "默认流转路径" 类似需要修改多个元素的事件发生的时候,更新表单的元素与原选中元素不一致。 if (element && element.id === this.elementId) { this.initFormOnChanged(element); } }); },
请注意其中的以下代码段:
this.processElement = window.bpmnInstances.elementRegistry.find(el => el.type === "bpmn:Process"); this.initFormOnChanged(this.processElement);
由于该方法只会在PropertiesPanel.vue组件第一次创建时被调用,并由上述代码段设置当前bpmnModeler上下文,而后续重新绘制流程图时未被调用,从而导致bpmnModeler上下文未更新
你不说我都没注意这个watch还没删了。。。等会儿我看看吧
我本地通过修改PropertiesPanel.vue组件中的initModels和getActiveElement方法,并添加了reinitializeProcessElement方法,来暂时解决了这个问题。 主要思路为给bpmnModeler增加了一个'import.done'监听,当事件被触发时,重新执行ProcessPanel.vue的processElement初始化逻辑 不知是否可行? 代码如下:
initModels() {
// 初始化 modeler 以及其他 moddle
if (!this.bpmnModeler) {
// 避免加载时 流程图 并未加载完成
this.timer = setTimeout(() => this.initModels(), 10);
return;
}
if (this.timer) clearTimeout(this.timer);
window.bpmnInstances = {
modeler: this.bpmnModeler,
modeling: this.bpmnModeler.get("modeling"),
moddle: this.bpmnModeler.get("moddle"),
eventBus: this.bpmnModeler.get("eventBus"),
bpmnFactory: this.bpmnModeler.get("bpmnFactory"),
elementRegistry: this.bpmnModeler.get("elementRegistry"),
replace: this.bpmnModeler.get("replace"),
selection: this.bpmnModeler.get("selection")
};
//修改开始
this.bpmnModeler.on('import.done', event => this.reinitializeProcessElement())
this.reinitializeProcessElement()
this.getActiveElement();
//修改开始
},
reinitializeProcessElement() {
// 初始第一个选中元素 bpmn:Process
this.processElement = window.bpmnInstances.elementRegistry.find(el => el.type === "bpmn:Process");
this.initFormOnChanged(this.processElement);
},
getActiveElement() {
//将原来此处的代码挪至reinitializeProcessElement方法中
// 监听选择事件,修改当前激活的元素以及表单
this.bpmnModeler.on("selection.changed", ({ newSelection }) => {
if (newSelection && newSelection.length) {
const element = newSelection[0];
this.initFormOnChanged(element);
} else {
this.initFormOnChanged(this.processElement);
}
});
this.bpmnModeler.on("element.changed", ({ element }) => {
// 保证 修改 "默认流转路径" 类似需要修改多个元素的事件发生的时候,更新表单的元素与原选中元素不一致。
if (element && element.id === this.elementId) {
this.initFormOnChanged(element);
}
});
},
你这个方式也是可以的
ok Thanks~
使用Vue Devtools修改App中ControlForm中的value属性,以使MyProcessDesigner组件重新渲染流程设计器 修改后的渲染结果出现多组件之间状态不一致的情况
默认初始化的xml内容 `<?xml version="1.0" encoding="UTF-8"?>