mirror of
https://github.com/Tencent/tmagic-editor.git
synced 2025-04-05 07:27:09 +08:00
refactor(editor): 优化dsl更新后画布更新逻辑
This commit is contained in:
parent
895c461e2b
commit
ab7df6c21e
@ -1,6 +1,7 @@
|
||||
import { computed, onBeforeUnmount, reactive, toRaw, watch } from 'vue';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
|
||||
import type TMagicCore from '@tmagic/core';
|
||||
import type {
|
||||
CodeBlockContent,
|
||||
DataSourceSchema,
|
||||
@ -263,67 +264,46 @@ export const initServiceEvents = (
|
||||
|
||||
if (!node) return;
|
||||
|
||||
collectIdle([node], true).then(() => {
|
||||
afterUpdateNodes([node]);
|
||||
});
|
||||
collectIdle([node], true);
|
||||
updateStage([node]);
|
||||
});
|
||||
});
|
||||
|
||||
const getApp = () => stage.value?.renderer?.runtime?.getApp?.();
|
||||
|
||||
const updateDataSourceSchema = (nodes: MNode[], deep: boolean) => {
|
||||
const root = editorService.get('root');
|
||||
const app = getApp();
|
||||
|
||||
if (root && app?.dsl) {
|
||||
app.dsl.dataSourceDeps = root.dataSourceDeps;
|
||||
app.dsl.dataSourceCondDeps = root.dataSourceCondDeps;
|
||||
app.dsl.dataSources = root.dataSources;
|
||||
const getApp = () => {
|
||||
const renderer = stage.value?.renderer;
|
||||
if (!renderer) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (root?.dataSources) {
|
||||
getApp()?.dataSourceManager?.updateSchema(root.dataSources);
|
||||
if (renderer.runtime) {
|
||||
return renderer.runtime.getApp?.();
|
||||
}
|
||||
|
||||
if (!root || !stage.value) return;
|
||||
return new Promise<TMagicCore | undefined>((resolve) => {
|
||||
const timeout = globalThis.setTimeout(() => {
|
||||
resolve(undefined);
|
||||
}, 10000);
|
||||
|
||||
const allNodes: MNode[] = [];
|
||||
|
||||
if (deep) {
|
||||
nodes.forEach((node) => {
|
||||
traverseNode<MNode>(node, (node) => {
|
||||
if (!allNodes.includes(node)) {
|
||||
allNodes.push(node);
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
allNodes.push(...nodes);
|
||||
}
|
||||
|
||||
const deps = Object.values(root.dataSourceDeps || {});
|
||||
deps.forEach((dep) => {
|
||||
Object.keys(dep).forEach((id) => {
|
||||
const node = allNodes.find((node) => node.id === id);
|
||||
node &&
|
||||
stage.value?.update({
|
||||
config: cloneDeep(node),
|
||||
parentId: editorService.getParentById(node.id)?.id,
|
||||
root: cloneDeep(root),
|
||||
});
|
||||
renderer.on('runtime-ready', () => {
|
||||
if (timeout) {
|
||||
globalThis.clearTimeout(timeout);
|
||||
}
|
||||
resolve(renderer.runtime?.getApp?.());
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
const afterUpdateNodes = (nodes: MNode[]) => {
|
||||
const updateDataSourceSchema = async () => {
|
||||
const root = editorService.get('root');
|
||||
if (!root) return;
|
||||
for (const node of nodes) {
|
||||
stage.value?.update({
|
||||
config: cloneDeep(node),
|
||||
parentId: editorService.getParentById(node.id)?.id,
|
||||
root: cloneDeep(root),
|
||||
});
|
||||
const app = await getApp();
|
||||
|
||||
if (root && app?.dsl) {
|
||||
app.dsl.dataSourceDeps = root.dataSourceDeps;
|
||||
app.dsl.dataSources = root.dataSources;
|
||||
}
|
||||
|
||||
if (root?.dataSources) {
|
||||
app?.dataSourceManager?.updateSchema(root.dataSources);
|
||||
}
|
||||
};
|
||||
|
||||
@ -360,18 +340,72 @@ export const initServiceEvents = (
|
||||
}
|
||||
};
|
||||
|
||||
const depCollectedHandler = () => {
|
||||
/**
|
||||
* 修改dsl后会执行依赖收集并调用此方法
|
||||
* 所以这个方法是会被执行两次,当时updateStage应当时一次,所以通过inDeps参数来区分调用时机
|
||||
* inDeps为true是则更新依赖收集到的节点,否则则更新没有依赖的节点
|
||||
* @param nodes 需要更新的节点
|
||||
* @param inDeps 是否依赖收集完成事件中执行的
|
||||
* @returns
|
||||
*/
|
||||
const updateStage = (nodes: MNode[], inDeps = false) => {
|
||||
const root = editorService.get('root');
|
||||
if (!root) return;
|
||||
const app = getApp();
|
||||
|
||||
const update = (node: MNode) =>
|
||||
stage.value?.update({
|
||||
config: cloneDeep(node),
|
||||
parentId: editorService.getParentById(node.id)?.id,
|
||||
root: cloneDeep(root),
|
||||
});
|
||||
|
||||
nodes.forEach((node) => {
|
||||
const inDepsNodeId: Id[] = [];
|
||||
const deps = Object.values(root.dataSourceDeps || {});
|
||||
deps.forEach((dep) => {
|
||||
Object.keys(dep).forEach((id) => {
|
||||
inDepsNodeId.push(id);
|
||||
});
|
||||
});
|
||||
|
||||
if (inDeps) {
|
||||
if (inDepsNodeId.includes(node.id)) {
|
||||
update(node);
|
||||
}
|
||||
} else {
|
||||
if (!inDepsNodeId.includes(node.id)) {
|
||||
update(node);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const dsDepCollectedHandler = async (nodes: MNode[], deep: boolean) => {
|
||||
const root = editorService.get('root');
|
||||
if (!root) return;
|
||||
const app = await getApp();
|
||||
if (app?.dsl) {
|
||||
app.dsl.dataSourceDeps = root.dataSourceDeps;
|
||||
}
|
||||
if (deep) {
|
||||
nodes.forEach((node) => {
|
||||
traverseNode<MNode>(
|
||||
node,
|
||||
(node) => {
|
||||
updateStage([node], true);
|
||||
},
|
||||
[],
|
||||
true,
|
||||
);
|
||||
});
|
||||
} else {
|
||||
updateStage(nodes, true);
|
||||
}
|
||||
};
|
||||
|
||||
depService.on('add-target', targetAddHandler);
|
||||
depService.on('remove-target', targetRemoveHandler);
|
||||
depService.on('collected', depCollectedHandler);
|
||||
depService.on('ds-collected', dsDepCollectedHandler);
|
||||
|
||||
const initDataSourceDepTarget = (ds: DataSourceSchema) => {
|
||||
depService.addTarget(createDataSourceTarget(ds, reactive({})));
|
||||
@ -396,9 +430,9 @@ export const initServiceEvents = (
|
||||
|
||||
// 新增节点,收集依赖
|
||||
const nodeAddHandler = (nodes: MNode[]) => {
|
||||
collectIdle(nodes, true).then(() => {
|
||||
afterUpdateNodes(nodes);
|
||||
});
|
||||
collectIdle(nodes, true);
|
||||
|
||||
updateStage(nodes);
|
||||
};
|
||||
|
||||
// 节点更新,收集依赖
|
||||
@ -430,11 +464,10 @@ export const initServiceEvents = (
|
||||
});
|
||||
|
||||
if (needRecollectNodes.length) {
|
||||
collectIdle(needRecollectNodes, true).then(() => {
|
||||
afterUpdateNodes(needRecollectNodes);
|
||||
});
|
||||
collectIdle(needRecollectNodes, true);
|
||||
updateStage(needRecollectNodes);
|
||||
} else if (normalNodes.length) {
|
||||
afterUpdateNodes(normalNodes);
|
||||
updateStage(normalNodes);
|
||||
}
|
||||
};
|
||||
|
||||
@ -446,7 +479,7 @@ export const initServiceEvents = (
|
||||
// 由于历史记录变化是更新整个page,所以历史记录变化时,需要重新收集依赖
|
||||
const historyChangeHandler = (page: MPage | MPageFragment) => {
|
||||
collectIdle([page], true).then(() => {
|
||||
updateDataSourceSchema([page], true);
|
||||
updateDataSourceSchema();
|
||||
});
|
||||
};
|
||||
|
||||
@ -472,12 +505,16 @@ export const initServiceEvents = (
|
||||
codeBlockService.on('addOrUpdate', codeBlockAddOrUpdateHandler);
|
||||
codeBlockService.on('remove', codeBlockRemoveHandler);
|
||||
|
||||
const dataSourceAddHandler = (config: DataSourceSchema) => {
|
||||
const dataSourceAddHandler = async (config: DataSourceSchema) => {
|
||||
initDataSourceDepTarget(config);
|
||||
getApp()?.dataSourceManager?.addDataSource(config);
|
||||
const app = await getApp();
|
||||
app?.dataSourceManager?.addDataSource(config);
|
||||
};
|
||||
|
||||
const dataSourceUpdateHandler = (config: DataSourceSchema, { changeRecords }: { changeRecords: ChangeRecord[] }) => {
|
||||
const dataSourceUpdateHandler = async (
|
||||
config: DataSourceSchema,
|
||||
{ changeRecords }: { changeRecords: ChangeRecord[] },
|
||||
) => {
|
||||
let needRecollectDep = false;
|
||||
for (const changeRecord of changeRecords) {
|
||||
if (!changeRecord.propPath) {
|
||||
@ -506,11 +543,12 @@ export const initServiceEvents = (
|
||||
initDataSourceDepTarget(config);
|
||||
|
||||
collectIdle(root.items, true).then(() => {
|
||||
updateDataSourceSchema(root?.items || [], true);
|
||||
updateDataSourceSchema();
|
||||
});
|
||||
}
|
||||
} else if (root?.dataSources) {
|
||||
getApp()?.dataSourceManager?.updateSchema(root.dataSources);
|
||||
const app = await getApp();
|
||||
app?.dataSourceManager?.updateSchema(root.dataSources);
|
||||
}
|
||||
};
|
||||
|
||||
@ -525,7 +563,7 @@ export const initServiceEvents = (
|
||||
const nodeIds = Object.keys(root?.dataSourceDeps?.[id] || {});
|
||||
const nodes = getNodes(nodeIds, root?.items);
|
||||
collectIdle(nodes, false).then(() => {
|
||||
updateDataSourceSchema(nodes, false);
|
||||
updateDataSourceSchema();
|
||||
});
|
||||
|
||||
removeDataSourceTarget(id);
|
||||
@ -538,7 +576,7 @@ export const initServiceEvents = (
|
||||
onBeforeUnmount(() => {
|
||||
depService.off('add-target', targetAddHandler);
|
||||
depService.off('remove-target', targetRemoveHandler);
|
||||
depService.off('collected', depCollectedHandler);
|
||||
depService.off('ds-collected', dsDepCollectedHandler);
|
||||
|
||||
editorService.off('history-change', historyChangeHandler);
|
||||
editorService.off('root-change', rootChangeHandler);
|
||||
|
@ -499,8 +499,11 @@ export const traverseNode = <T extends NodeItem = NodeItem>(
|
||||
node: T,
|
||||
cb: (node: T, parents: T[]) => void,
|
||||
parents: T[] = [],
|
||||
evalCbAfter = false,
|
||||
) => {
|
||||
cb(node, parents);
|
||||
if (!evalCbAfter) {
|
||||
cb(node, parents);
|
||||
}
|
||||
|
||||
if (Array.isArray(node.items) && node.items.length) {
|
||||
parents.push(node);
|
||||
@ -508,6 +511,10 @@ export const traverseNode = <T extends NodeItem = NodeItem>(
|
||||
traverseNode(item as T, cb, [...parents]);
|
||||
});
|
||||
}
|
||||
|
||||
if (evalCbAfter) {
|
||||
cb(node, parents);
|
||||
}
|
||||
};
|
||||
|
||||
export const isValueIncludeDataSource = (value: any) => {
|
||||
|
Loading…
x
Reference in New Issue
Block a user