historyService事件
page-change
详情: 页面切换
事件回调函数:
(undoRedo: UndoRedo) => void查看 UndoRedo 类定义
tsexport class UndoRedo<T = any> { private elementList: T[]; private listCursor: number; private listMaxSize: number; constructor(listMaxSize = 100) { const minListMaxSize = 2; this.elementList = []; this.listCursor = 0; this.listMaxSize = listMaxSize > minListMaxSize ? listMaxSize : minListMaxSize; } public pushElement(element: T): void { // 新元素进来时,把游标之外的元素全部丢弃,并把新元素放进来 this.elementList.splice(this.listCursor, this.elementList.length - this.listCursor, cloneDeep(element)); this.listCursor += 1; // 如果list中的元素超过maxSize,则移除第一个元素 if (this.elementList.length > this.listMaxSize) { this.elementList.shift(); this.listCursor -= 1; } } public canUndo(): boolean { return this.listCursor > 0; } /** 返回被撤销的操作 */ public undo(): T | null { if (!this.canUndo()) { return null; } this.listCursor -= 1; return cloneDeep(this.elementList[this.listCursor]); } public canRedo() { return this.elementList.length > this.listCursor; } /** 返回被重做的操作 */ public redo(): T | null { if (!this.canRedo()) { return null; } const element = cloneDeep(this.elementList[this.listCursor]); this.listCursor += 1; return element; } public getCurrentElement(): T | null { if (this.listCursor < 1) { return null; } return cloneDeep(this.elementList[this.listCursor - 1]); } /** * 返回栈内全部元素的浅克隆数组(按时间顺序,索引 0 为最早一步)。 * 仅用于历史面板等只读展示场景,不应直接修改返回值。 */ public getElementList(): T[] { return this.elementList.slice(); } /** * 当前游标位置:表示已应用的步骤数量。 * - cursor === 0 表示全部已撤销 * - cursor === length 表示已重做到末尾 * 历史面板用于区分"已应用 / 已撤销"两段。 */ public getCursor(): number { return this.listCursor; } /** 栈内总步数。 */ public getLength(): number { return this.elementList.length; } }
change
详情: 历史记录发生变化
事件回调函数:
(state: StepValue | null) => void查看 StepValue 及关联类型定义
tsexport interface StepValue { /** 页面信息 */ data: { name: string; id: Id }; opType: HistoryOpType; /** 操作前选中的节点 ID,用于撤销后恢复选择状态 */ selectedBefore: Id[]; /** 操作后选中的节点 ID,用于重做后恢复选择状态 */ selectedAfter: Id[]; modifiedNodeIds: Map<Id, Id>; /** opType 'add': 新增的节点 */ nodes?: MNode[]; /** opType 'add': 父节点 ID */ parentId?: Id; /** opType 'add': 每个新增节点在父节点 items 中的索引 */ indexMap?: Record<string, number>; /** opType 'remove': 被删除的节点及其位置信息 */ removedItems?: { node: MNode; parentId: Id; index: number }[]; /** * opType 'update': 变更前后的节点快照 * * `changeRecords` 来自 form 端的 propPath/value 列表,撤销/重做时只对这些 propPath 做局部更新; * 缺省(未传 / 空数组)才退化为整节点替换。 */ updatedItems?: { oldNode: MNode; newNode: MNode; changeRecords?: ChangeRecord[] }[]; /** * 调用方可选传入的人类可读描述(如「调整按钮颜色」),用于历史面板展示。 * 不影响 undo/redo 行为;缺省时面板会根据节点 / propPath 自动生成描述。 */ historyDescription?: string; /** * 操作途径:标记本次变更由哪条交互入口触发,取值见 {@link HistoryOpSource} * (画布 / 树面板 / 组件面板 / 配置面板 / 源码编辑器 / 右键菜单 / 工具栏 / 快捷键 / 回滚 / 接口 等)。 * 仅用于历史面板展示与业务埋点,不影响 undo/redo 行为;缺省时面板视为「未知」。 */ source?: HistoryOpSource; /** * 入栈时间戳(毫秒)。在 historyService.push 时自动写入(若调用方未指定),仅用于历史面板展示。 */ timestamp?: number; }tsexport type HistoryOpType = 'add' | 'remove' | 'update';ts/** * 历史记录的「操作途径」——标记本次变更由哪条交互入口触发,仅用于历史面板展示 / 业务埋点, * 不影响 undo/redo 行为。缺省(未传)时 UI 视为「未知」。 * * - `stage`:画布(拖拽 / 缩放 / 排序等舞台直接操作) * - `tree`:树形面板(图层 / 数据源 / 代码块等树形结构里的拖拽 / 菜单操作) * - `component-panel`:组件面板(左侧组件列表点击 / 拖拽新增组件) * - `props`:配置面板表单(属性表单字段编辑) * - `code`:源码编辑器(配置面板「源码」面板里直接编辑 JSON/代码后保存) * - `stage-contextmenu`:画布右键菜单(舞台上节点的右键上下文菜单) * - `tree-contextmenu`:树面板右键菜单(图层 / 数据源 / 代码块等树形列表上的右键上下文菜单) * - `toolbar`:工具栏菜单(顶部导航工具栏按钮) * - `shortcut`:键盘快捷键 * - `rollback`:历史回滚(历史面板里对某条历史「回滚」,反向应用为一条新记录,类 git revert) * - `api`:代码 / 接口调用(程序化触发) * - `ai`:AI 生成 / 智能助手触发的变更 * - `unknown`:未知来源 * * 通过 `(string & {})` 允许业务侧扩展自定义途径字符串,同时保留内置值的自动补全。 */ export type HistoryOpSource = | 'stage' | 'tree' | 'component-panel' | 'props' | 'code' | 'stage-contextmenu' | 'tree-contextmenu' | 'toolbar' | 'shortcut' | 'rollback' | 'api' | 'ai' | 'unknown' | (string & {});tsexport type Id = string | number;tsexport type MNode = MComponent | MContainer | MIteratorContainer | MPage | MApp | MPageFragment;TIP
当游标处于历史栈边界(已经无法继续撤销或重做)时,
UndoRedo.undo()/redo()返回null,对应change回调收到的state为null
code-block-history-change
详情: 代码块历史记录发生变化(
pushCodeBlock/undoCodeBlock/redoCodeBlock成功时触发)事件回调函数:
(codeBlockId: Id, step: CodeBlockStepValue) => void查看 CodeBlockStepValue 及关联类型定义
ts/** * 代码块历史记录条目。按 codeBlock.id 分组保存到 historyState.codeBlockState。 * - 新增:oldContent = null,newContent = 新内容 * - 更新:oldContent / newContent 都为对应内容 * - 删除:newContent = null,oldContent = 删除前内容 */ export interface CodeBlockStepValue { /** 关联的代码块 id */ id: Id; /** 变更前的代码块内容,新增时为 null */ oldContent: CodeBlockContent | null; /** 变更后的代码块内容,删除时为 null */ newContent: CodeBlockContent | null; /** * form 端 propPath/value 列表。撤销/重做时若有则按 propPath 局部更新; * 缺省才退化为整内容替换。新增/删除场景通常无 changeRecords。 */ changeRecords?: ChangeRecord[]; /** 调用方可选传入的人类可读描述,用于历史面板展示;不影响 undo/redo 行为。 */ historyDescription?: string; /** 操作途径:标记本次变更由哪条交互入口触发,取值见 {@link HistoryOpSource};仅用于历史面板展示与埋点,不影响 undo/redo 行为。 */ source?: HistoryOpSource; /** 入栈时间戳(毫秒),入栈时自动写入,仅用于历史面板展示。 */ timestamp?: number; }ts/** * 历史记录的「操作途径」——标记本次变更由哪条交互入口触发,仅用于历史面板展示 / 业务埋点, * 不影响 undo/redo 行为。缺省(未传)时 UI 视为「未知」。 * * - `stage`:画布(拖拽 / 缩放 / 排序等舞台直接操作) * - `tree`:树形面板(图层 / 数据源 / 代码块等树形结构里的拖拽 / 菜单操作) * - `component-panel`:组件面板(左侧组件列表点击 / 拖拽新增组件) * - `props`:配置面板表单(属性表单字段编辑) * - `code`:源码编辑器(配置面板「源码」面板里直接编辑 JSON/代码后保存) * - `stage-contextmenu`:画布右键菜单(舞台上节点的右键上下文菜单) * - `tree-contextmenu`:树面板右键菜单(图层 / 数据源 / 代码块等树形列表上的右键上下文菜单) * - `toolbar`:工具栏菜单(顶部导航工具栏按钮) * - `shortcut`:键盘快捷键 * - `rollback`:历史回滚(历史面板里对某条历史「回滚」,反向应用为一条新记录,类 git revert) * - `api`:代码 / 接口调用(程序化触发) * - `ai`:AI 生成 / 智能助手触发的变更 * - `unknown`:未知来源 * * 通过 `(string & {})` 允许业务侧扩展自定义途径字符串,同时保留内置值的自动补全。 */ export type HistoryOpSource = | 'stage' | 'tree' | 'component-panel' | 'props' | 'code' | 'stage-contextmenu' | 'tree-contextmenu' | 'toolbar' | 'shortcut' | 'rollback' | 'api' | 'ai' | 'unknown' | (string & {});tsexport interface CodeBlockContent { /** 代码块名称 */ name: string; /** 代码块内容 */ content: ((...args: any[]) => any) | Function; /** 参数定义 */ params: CodeParam[] | []; /** 注释 */ desc?: string; /** 扩展字段 */ [propName: string]: any; }tsexport type Id = string | number;TIP
- 新增触发的 step 中
oldContent为null - 删除触发的 step 中
newContent为null undo/redo返回null(边界状态)时不会触发该事件
- 新增触发的 step 中
data-source-history-change
详情: 数据源历史记录发生变化(
pushDataSource/undoDataSource/redoDataSource成功时触发)事件回调函数:
(dataSourceId: Id, step: DataSourceStepValue) => void查看 DataSourceStepValue 及关联类型定义
ts/** * 数据源历史记录条目。按 dataSource.id 分组保存到 historyState.dataSourceState。 * - 新增:oldSchema = null,newSchema = 新 schema * - 更新:oldSchema / newSchema 都为对应 schema * - 删除:newSchema = null,oldSchema = 删除前 schema */ export interface DataSourceStepValue { /** 关联的数据源 id */ id: Id; /** 变更前的数据源 schema,新增时为 null */ oldSchema: DataSourceSchema | null; /** 变更后的数据源 schema,删除时为 null */ newSchema: DataSourceSchema | null; /** * form 端 propPath/value 列表。撤销/重做时若有则按 propPath 局部更新; * 缺省才退化为整 schema 替换。新增/删除场景通常无 changeRecords。 */ changeRecords?: ChangeRecord[]; /** 调用方可选传入的人类可读描述,用于历史面板展示;不影响 undo/redo 行为。 */ historyDescription?: string; /** 操作途径:标记本次变更由哪条交互入口触发,取值见 {@link HistoryOpSource};仅用于历史面板展示与埋点,不影响 undo/redo 行为。 */ source?: HistoryOpSource; /** 入栈时间戳(毫秒),入栈时自动写入,仅用于历史面板展示。 */ timestamp?: number; }ts/** * 历史记录的「操作途径」——标记本次变更由哪条交互入口触发,仅用于历史面板展示 / 业务埋点, * 不影响 undo/redo 行为。缺省(未传)时 UI 视为「未知」。 * * - `stage`:画布(拖拽 / 缩放 / 排序等舞台直接操作) * - `tree`:树形面板(图层 / 数据源 / 代码块等树形结构里的拖拽 / 菜单操作) * - `component-panel`:组件面板(左侧组件列表点击 / 拖拽新增组件) * - `props`:配置面板表单(属性表单字段编辑) * - `code`:源码编辑器(配置面板「源码」面板里直接编辑 JSON/代码后保存) * - `stage-contextmenu`:画布右键菜单(舞台上节点的右键上下文菜单) * - `tree-contextmenu`:树面板右键菜单(图层 / 数据源 / 代码块等树形列表上的右键上下文菜单) * - `toolbar`:工具栏菜单(顶部导航工具栏按钮) * - `shortcut`:键盘快捷键 * - `rollback`:历史回滚(历史面板里对某条历史「回滚」,反向应用为一条新记录,类 git revert) * - `api`:代码 / 接口调用(程序化触发) * - `ai`:AI 生成 / 智能助手触发的变更 * - `unknown`:未知来源 * * 通过 `(string & {})` 允许业务侧扩展自定义途径字符串,同时保留内置值的自动补全。 */ export type HistoryOpSource = | 'stage' | 'tree' | 'component-panel' | 'props' | 'code' | 'stage-contextmenu' | 'tree-contextmenu' | 'toolbar' | 'shortcut' | 'rollback' | 'api' | 'ai' | 'unknown' | (string & {});tsexport type Id = string | number;TIP
- 新增触发的 step 中
oldSchema为null - 删除触发的 step 中
newSchema为null undo/redo返回null(边界状态)时不会触发该事件
- 新增触发的 step 中