UNPKG

jbxl-workflow

Version:

流程图

128 lines (115 loc) 5.09 kB
// utils/proxy.js import { Graph } from "@antv/x6"; // import { createX6Binder } from "@/utils/common"; const whiteList = ['setZIndex'] // 在白名单内的方法不进行代理 export function createX6Binder(data, x6Node, options = {}) { const { exclude = [], mapping = {}, direction = 'both' } = options; const x6Properties = new Set(['id', 'shape', 'ports', 'zIndex']); let isSyncing = false; // 深度克隆并合并数据(避免引用问题) const mergeData = (target, source) => { return { ...target, ...source }; }; // 创建深层代理 const createDeepProxy = (target, isX6) => { return new Proxy(target, { get(t, prop) { // 处理属性映射 const mappedProp = mapping[prop] || prop; const value = Reflect.get(t, mappedProp); // 跳过 X6 特殊属性 if (isX6 && x6Properties.has(mappedProp)) { return value; } // 自动代理嵌套对象 if (typeof value === 'object' && value !== null && !exclude.includes(mappedProp)) { return createDeepProxy(value, isX6); } return value; }, set(t, prop, value) { if (isSyncing) return true; const mappedProp = mapping[prop] || prop; if (exclude.includes(mappedProp)) return true; try { isSyncing = true; // 双向同步逻辑 if (direction !== 'toData') { // 更新数据对象 Reflect.set(t, mappedProp, value); } if (direction !== 'toX6') { // 关键修改:调用 setData 而不是直接修改属性 // const targetObj = isX6 ? data : x6Node; const targetKey = Object.entries(mapping) .find(([k, v]) => v === mappedProp)?.[0] || mappedProp; // 获取当前数据并合并更新 const currentData = isX6 ? data : x6Node.getData(); const newData = mergeData(currentData, { [targetKey]: value }); // 调用 setData 触发 X6 更新 if (isX6) { x6Node.setData(newData); } else { const {data, self} = newData || {} self.setData(data) // TODO: 这里的逻辑有待优化,可能需要更精确地处理嵌套属性的更新,如果x6更新有问题的话,可能要将这个targetObj改回来,或者直接改成X6的setData方法 /** * targetObj.setData(newData); * */ // x6Node.setData(newData); } } return true; } finally { isSyncing = false; } } }); }; return [ createDeepProxy(data, false), createDeepProxy(x6Node, true) ]; } const nodeProxyMap = new WeakMap(); // 创建代理后的 Graph 实例 export const createGraph = (options) => { // 初始化原始 X6 实例 const rawGraph = new Graph(options); // 创建代理实例 const graphProxy = createGraphProxy(rawGraph); window.customGraph = graphProxy; return graphProxy; }; // 代理工厂 export const createGraphProxy = (graph) => { return new Proxy(graph, { get(target, prop) { // 拦截 addNode:绑定业务对象 if (prop === 'addNode') { return (params) => { // 从参数中提取业务对象 const businessObj = params.data?.self; if (!businessObj) throw new Error('Missing self object in node data'); // 创建原始 X6 节点 const rawNode = target.addNode(params); businessObj.nodeId = rawNode.id; // 设置节点 ID 以便后续引用 // 创建一个特殊的代理,处理 setZIndex 等方法 // 创建双向绑定代理 const [businessProxy, x6Proxy] = createX6Binder(businessObj, rawNode); // 缓存代理关系 nodeProxyMap.set(rawNode, businessProxy); return [businessProxy, x6Proxy]; // 返回业务代理对象 }; } // 拦截 getNode:返回业务代理对象 if (prop === 'getNode') { return (nodeId) => { const rawNode = target.getNode(nodeId); return nodeProxyMap.get(rawNode) || null; }; } return Reflect.get(target, prop); } }); };