保存
This commit is contained in:
149
.qoder/repowiki/zh/content/事件系统/窗口表单事件管理器/窗口数据更新事件.md
Normal file
149
.qoder/repowiki/zh/content/事件系统/窗口表单事件管理器/窗口数据更新事件.md
Normal file
@@ -0,0 +1,149 @@
|
||||
# 窗口数据更新事件
|
||||
|
||||
<cite>
|
||||
**本文档引用文件**
|
||||
- [WindowFormEventManager.ts](file://src/events/WindowFormEventManager.ts)
|
||||
- [WindowService.ts](file://src/services/WindowService.ts)
|
||||
- [WindowFormTypes.ts](file://src/ui/types/WindowFormTypes.ts)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [IWindowFormDataUpdateParams接口字段语义解析](#iwindowformdataupdateparams接口字段语义解析)
|
||||
3. [TWindowFormState类型关联说明](#twindowformstatetype类型关联说明)
|
||||
4. [窗口拖拽、缩放与状态切换中的统一元数据发送机制](#窗口拖拽缩放与状态切换中的统一元数据发送机制)
|
||||
5. [接收端批量更新UI的TypeScript示例](#接收端批量更新ui的typescript示例)
|
||||
6. [高频更新性能优化建议:防抖策略](#高频更新性能优化建议防抖策略)
|
||||
7. [窗口状态实时同步与持久化存储支持机制](#窗口状态实时同步与持久化存储支持机制)
|
||||
|
||||
## 简介
|
||||
`windowFormDataUpdate` 事件是桌面应用中用于传递窗口最新元数据的核心通信机制。该事件在窗口发生位置移动、尺寸调整或状态变更(如最小化、最大化)时触发,通过 `IWindowFormDataUpdateParams` 接口统一封装窗口的ID、状态、尺寸和坐标信息,并广播至所有监听者。此设计实现了窗口状态变化的集中通知与响应,为UI同步、布局管理及状态持久化提供了基础支撑。
|
||||
|
||||
**Section sources**
|
||||
- [WindowFormEventManager.ts](file://src/events/WindowFormEventManager.ts#L37-L37)
|
||||
|
||||
## IWindowFormDataUpdateParams接口字段语义解析
|
||||
`IWindowFormDataUpdateParams` 接口定义了窗口更新事件所携带的数据结构,包含以下关键字段:
|
||||
|
||||
- **id**: 字符串类型,表示窗口的唯一标识符。该ID由系统生成并贯穿窗口生命周期,用于精确识别和定位特定窗口实例。
|
||||
- **state**: 枚举类型 `TWindowFormState`,表示当前窗口的状态,包括 `'default'`(默认)、`'minimized'`(最小化)、`'maximized'`(最大化)三种可能值。
|
||||
- **width**: 数字类型,表示窗口当前的宽度(单位:像素),反映窗口水平方向的实际尺寸。
|
||||
- **height**: 数字类型,表示窗口当前的高度(单位:像素),反映窗口垂直方向的实际尺寸。
|
||||
- **x**: 数字类型,表示窗口左上角相对于屏幕原点的X轴坐标(单位:像素),用于确定窗口的水平位置。
|
||||
- **y**: 数字类型,表示窗口左上角相对于屏幕原点的Y轴坐标(单位:像素),用于确定窗口的垂直位置。
|
||||
|
||||
这些字段共同构成了窗口的完整元数据快照,确保接收方能够准确还原窗口的视觉表现和行为状态。
|
||||
|
||||
**Section sources**
|
||||
- [WindowFormEventManager.ts](file://src/events/WindowFormEventManager.ts#L44-L57)
|
||||
|
||||
## TWindowFormState类型关联说明
|
||||
`TWindowFormState` 是一个字符串联合类型,明确定义了窗口可处于的三种核心状态:
|
||||
- `'default'`: 窗口处于正常显示状态,既非最大化也非最小化。
|
||||
- `'minimized'`: 窗口被最小化,通常从主视图隐藏,仅在任务栏或启动器中保留图标。
|
||||
- `'maximized'`: 窗口被最大化,占据除任务栏外的整个屏幕空间。
|
||||
|
||||
该类型与 `IWindowFormDataUpdateParams.state` 字段直接关联,作为事件数据的一部分,在窗口状态发生变化时(例如用户点击最大化按钮),新的状态值将被封装进事件参数中并广播出去。这种强类型的约束保证了状态传递的准确性与一致性。
|
||||
|
||||
**Section sources**
|
||||
- [WindowFormTypes.ts](file://src/ui/types/WindowFormTypes.ts#L9-L9)
|
||||
|
||||
## 窗口拖拽、缩放与状态切换中的统一元数据发送机制
|
||||
无论窗口因何种操作而改变其外观或状态,系统均通过 `windowFormDataUpdate` 事件统一发送最新的元数据。具体流程如下:
|
||||
|
||||
1. **拖拽操作**:当用户拖动窗口标题栏时,鼠标移动事件会持续更新窗口的 `x` 和 `y` 坐标。在每次坐标更新后,系统调用 `setActiveWindow` 激活该窗口,并最终通过事件总线触发 `windowFormDataUpdate`,附带更新后的坐标、尺寸及当前状态。
|
||||
2. **缩放操作**:当用户调整窗口大小时,`setWindowSize` 方法被调用以更新 `width` 和 `height`。此方法不仅修改DOM样式,还会通知事件总线,从而触发包含新尺寸的 `windowFormDataUpdate` 事件。
|
||||
3. **状态切换**:无论是最小化、最大化还是还原操作,都会先调用 `updateWindowState` 修改内部状态机,随后根据新状态调整DOM表现(如隐藏元素或全屏展示)。最后,系统发出 `windowFormDataUpdate` 事件,其中 `state` 字段反映最新状态,同时附带相应的坐标和尺寸信息。
|
||||
|
||||
这一机制确保了所有窗口变更都通过单一入口进行通知,简化了状态管理逻辑,避免了多事件源导致的不一致问题。
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[用户操作] --> B{操作类型}
|
||||
B --> |拖拽| C[更新 x, y]
|
||||
B --> |缩放| D[更新 width, height]
|
||||
B --> |状态切换| E[更新 state]
|
||||
C --> F[调用 setActiveWindow]
|
||||
D --> G[调用 setWindowSize]
|
||||
E --> H[调用 updateWindowState]
|
||||
F --> I[触发 windowFormDataUpdate]
|
||||
G --> I
|
||||
H --> I
|
||||
I --> J[接收端更新UI]
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [WindowService.ts](file://src/services/WindowService.ts#L512-L552)
|
||||
- [WindowService.ts](file://src/services/WindowService.ts#L248-L304)
|
||||
- [WindowService.ts](file://src/services/WindowService.ts#L179-L213)
|
||||
|
||||
**Section sources**
|
||||
- [WindowService.ts](file://src/services/WindowService.ts#L512-L552)
|
||||
- [WindowService.ts](file://src/services/WindowService.ts#L248-L304)
|
||||
- [WindowService.ts](file://src/services/WindowService.ts#L179-L213)
|
||||
|
||||
## 接收端批量更新UI的TypeScript示例
|
||||
接收 `windowFormDataUpdate` 事件后,应使用接收到的完整数据对象一次性批量更新UI,避免逐个属性设置带来的性能开销和视觉闪烁。以下为推荐的处理方式:
|
||||
|
||||
```typescript
|
||||
wfem.addEventListener('windowFormDataUpdate', (data) => {
|
||||
const { id, state, width, height, x, y } = data;
|
||||
const windowElement = document.getElementById(`window-${id}`);
|
||||
|
||||
if (!windowElement) return;
|
||||
|
||||
// 批量更新样式属性
|
||||
Object.assign(windowElement.style, {
|
||||
width: `${width}px`,
|
||||
height: `${height}px`,
|
||||
left: `${x}px`,
|
||||
top: `${y}px`,
|
||||
display: state === 'minimized' ? 'none' : 'block'
|
||||
});
|
||||
|
||||
// 根据状态添加CSS类以支持主题化样式
|
||||
windowElement.classList.toggle('maximized', state === 'maximized');
|
||||
windowElement.classList.toggle('minimized', state === 'minimized');
|
||||
windowElement.classList.toggle('default', state === 'default');
|
||||
});
|
||||
```
|
||||
|
||||
上述代码利用 `Object.assign` 对目标DOM元素的样式进行原子性更新,确保浏览器只进行一次重排(reflow)和重绘(repaint),从而提升渲染效率。
|
||||
|
||||
**Section sources**
|
||||
- [WindowFormEventManager.ts](file://src/events/WindowFormEventManager.ts#L37-L37)
|
||||
|
||||
## 高频更新性能优化建议:防抖策略
|
||||
由于拖拽和缩放操作会产生大量连续的 `windowFormDataUpdate` 事件,若不对处理函数加以节流,可能导致UI线程阻塞或频繁重绘,影响用户体验。为此,建议对接收端的事件处理器应用防抖(debounce)技术:
|
||||
|
||||
```typescript
|
||||
function debounce<T extends (...args: any[]) => void>(func: T, delay: number): T {
|
||||
let timeoutId: ReturnType<typeof setTimeout>;
|
||||
return function (this: any, ...args: any[]) {
|
||||
clearTimeout(timeoutId);
|
||||
timeoutId = setTimeout(() => func.apply(this, args), delay);
|
||||
} as T;
|
||||
}
|
||||
|
||||
const debouncedHandler = debounce((data: IWindowFormDataUpdateParams) => {
|
||||
// 执行UI更新逻辑
|
||||
}, 16); // 约60fps的间隔
|
||||
|
||||
wfem.addEventListener('windowFormDataUpdate', debouncedHandler);
|
||||
```
|
||||
|
||||
通过设置约16毫秒的延迟(对应60Hz刷新率),可以有效过滤掉中间过渡状态,仅处理最终稳定的位置或尺寸,显著降低计算负担并提升流畅度。
|
||||
|
||||
**Section sources**
|
||||
- [WindowFormEventManager.ts](file://src/events/WindowFormEventManager.ts#L44-L57)
|
||||
|
||||
## 窗口状态实时同步与持久化存储支持机制
|
||||
`windowFormDataUpdate` 事件不仅是UI更新的驱动源,也为跨组件通信和状态持久化提供了可靠的数据通道。任何需要感知窗口状态的模块(如任务栏、窗口管理器、布局保存服务)均可订阅此事件,实现状态的实时同步。
|
||||
|
||||
此外,通过监听该事件,可将窗口的 `id`、`state`、`width`、`height`、`x`、`y` 等元数据记录到本地存储(如localStorage)或远程服务器,实现用户偏好的记忆功能。例如,在用户下次启动应用时,系统可根据存储的历史数据恢复窗口的原始位置和大小,提供一致的使用体验。
|
||||
|
||||
该事件的设计使得状态采集与业务逻辑解耦,任何持久化逻辑只需作为事件观察者存在,无需侵入窗口控制核心代码,符合关注点分离原则。
|
||||
|
||||
**Section sources**
|
||||
- [WindowFormEventManager.ts](file://src/events/WindowFormEventManager.ts#L37-L37)
|
||||
- [WindowService.ts](file://src/services/WindowService.ts#L67-L118)
|
||||
Reference in New Issue
Block a user