mirror of
https://github.com/Tencent/tmagic-editor.git
synced 2026-09-12 15:09:43 +00:00
fix(editor): 避免 defaultSelected 早于 root 就绪时 select 抛出未处理错误
This commit is contained in:
parent
58f2a943b8
commit
08b610a4f2
@ -29,6 +29,7 @@ import { getDepNodeIds, getNodes, isPage, isValueIncludeDataSource } from '@tmag
|
||||
|
||||
import PropsPanel from './layouts/PropsPanel.vue';
|
||||
import { isIncludeDataSource } from './utils/editor';
|
||||
import { error as logError } from './utils/logger';
|
||||
import { EditorProps } from './editorProps';
|
||||
import { Services } from './type';
|
||||
|
||||
@ -36,6 +37,19 @@ export declare type LooseRequired<T> = {
|
||||
[P in string & keyof T]: T[P];
|
||||
};
|
||||
|
||||
/**
|
||||
* select 为异步串行执行,节点不可选中(如已从 DSL 中移除)时会抛错。
|
||||
* 在 watch 回调中调用不能把拒绝抛回调用方,否则会变成 Vue 的「Unhandled error during execution of watcher callback」,
|
||||
* 这里统一兜底成日志。
|
||||
*/
|
||||
const selectNode = async (editorService: Services['editorService'], id: Id) => {
|
||||
try {
|
||||
await editorService.select(id);
|
||||
} catch (e) {
|
||||
logError(e);
|
||||
}
|
||||
};
|
||||
|
||||
export const initServiceState = (
|
||||
props: EditorProps,
|
||||
{
|
||||
@ -193,9 +207,17 @@ export const initServiceState = (
|
||||
},
|
||||
);
|
||||
|
||||
// defaultSelected 可能早于 modelValue 到位(immediate 首次执行时 root 还是空的,或节点尚未出现在 DSL 中),
|
||||
// 此时 select 会因为「获取不到组件信息」而抛错,交由 root-change 中的选中逻辑在 root 就绪后补上即可。
|
||||
watch(
|
||||
() => props.defaultSelected,
|
||||
(defaultSelected) => defaultSelected && editorService.select(defaultSelected),
|
||||
(defaultSelected) => {
|
||||
if (!defaultSelected || !editorService.getNodeById(defaultSelected)) {
|
||||
return;
|
||||
}
|
||||
|
||||
selectNode(editorService, defaultSelected);
|
||||
},
|
||||
{
|
||||
immediate: true,
|
||||
},
|
||||
|
||||
@ -4,12 +4,13 @@
|
||||
* Copyright (C) 2025 Tencent.
|
||||
*/
|
||||
import { beforeEach, describe, expect, test, vi } from 'vitest';
|
||||
import { defineComponent, h } from 'vue';
|
||||
import { defineComponent, h, nextTick } from 'vue';
|
||||
import { mount } from '@vue/test-utils';
|
||||
|
||||
import { DepTargetType } from '@tmagic/core';
|
||||
|
||||
import { initServiceEvents, initServiceState } from '@editor/initService';
|
||||
import * as logger from '@editor/utils/logger';
|
||||
|
||||
const mkServices = () => {
|
||||
const handlers: Record<string, Record<string, any[]>> = {};
|
||||
@ -151,6 +152,10 @@ vi.mock('@editor/utils/editor', () => ({
|
||||
isIncludeDataSource: vi.fn(() => false),
|
||||
}));
|
||||
|
||||
vi.mock('@editor/utils/logger', () => ({
|
||||
error: vi.fn(),
|
||||
}));
|
||||
|
||||
const Wrap = (props: any, services: any) =>
|
||||
defineComponent({
|
||||
setup() {
|
||||
@ -233,11 +238,30 @@ describe('initServiceState', () => {
|
||||
});
|
||||
|
||||
test('defaultSelected 调用 select', () => {
|
||||
services.editorService.getNodeById.mockReturnValue({ id: 'n1' });
|
||||
const props = { defaultSelected: 'n1' } as any;
|
||||
mount(Wrap(props, services));
|
||||
expect(services.editorService.select).toHaveBeenCalledWith('n1');
|
||||
});
|
||||
|
||||
test('defaultSelected 对应节点不存在时不调用 select', () => {
|
||||
services.editorService.getNodeById.mockReturnValue(null);
|
||||
const props = { defaultSelected: 'n1' } as any;
|
||||
mount(Wrap(props, services));
|
||||
expect(services.editorService.select).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('defaultSelected select 失败时兜底成日志,不产生未处理的拒绝', async () => {
|
||||
const err = new Error('获取不到组件信息');
|
||||
vi.mocked(logger.error).mockClear();
|
||||
services.editorService.getNodeById.mockReturnValue({ id: 'n1' });
|
||||
services.editorService.select.mockRejectedValue(err);
|
||||
const props = { defaultSelected: 'n1' } as any;
|
||||
mount(Wrap(props, services));
|
||||
await nextTick();
|
||||
expect(logger.error).toHaveBeenCalledWith(err);
|
||||
});
|
||||
|
||||
test('stageRect 设置 ui state', () => {
|
||||
const props = { stageRect: { width: 100 } } as any;
|
||||
mount(Wrap(props, services));
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user