V1.0.0
Skip to content

Window 事件监听

如果你在 Vue 项目中使用 A2UI,请用 processor.onEvent() 等方法,详见 Processor API - 事件监听

如果你在 原生 JS 或 React 等非 Vue 环境中使用 A2UI,用 window.addEventListener 监听事件,这就是本文档要讲的。


三种事件

事件事件名触发时机用途
页面创建win-design-a2ui-surface-createdSurface 创建完成,组件还没渲染设置初始数据
渲染完成win-design-a2ui-rendered组件树渲染完毕操作组件、获取实例
用户操作win-design-a2ui-event用户点击按钮、输入文字等处理业务逻辑

WARNING

  • 用户操作事件中,必须调用 respond([]),否则页面会卡住
  • 前两种事件不需要调用 respond
  • window 事件是全局的,页面有多个 A2UI 实例时,需要用 surfaceId 区分

完整示例

typescript
// ━━━ 事件 1:页面创建 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// 组件还没渲染。适合设置初始数据。
window.addEventListener('win-design-a2ui-surface-created', (e: Event) => {
  const {
    surfaceId, // 页面标识
    surface, // Surface 实例
    updateDataModel, // 设置数据的方法
    getDataValue, // 读取数据的方法
    getFormInstance, // 获取表单实例的方法
    getPangoEditorInstance, // 获取编辑器实例的方法
    getPangoEditorParams, // 获取编辑器数据的方法
    eventInputParams, // createSurface 时传入的业务参数
  } = (e as CustomEvent).detail;

  if (surfaceId !== 'my_surface') return; // ⚠️ 必须手动判断是哪个页面

  // 设置初始数据
  updateDataModel(surfaceId, '/userName', '');
  updateDataModel(surfaceId, '/clickCount', 0);
});

// ━━━ 事件 2:渲染完成 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// 组件都渲染好了。适合操作组件或获取实例。
window.addEventListener('win-design-a2ui-rendered', (e: Event) => {
  const {
    surfaceId,
    componentCount, // 渲染了多少个组件
    updateComponentProp, // 更新组件属性的方法
    getDataValue,
    getFormInstance,
    getPangoEditorInstance,
    getPangoEditorParams,
  } = (e as CustomEvent).detail;

  if (surfaceId !== 'my_surface') return;

  // 比如把提交按钮设为可用
  updateComponentProp(surfaceId, 'btn_submit', 'disabled', false);

  // 获取实例
  const form = getFormInstance('form_001');
  const editor = getPangoEditorInstance('editor-001');
});

// ━━━ 事件 3:用户操作 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// 用户点击了按钮、输入了文字等。
// ⚠️ 处理完后必须调用 respond(),否则页面会卡住!
window.addEventListener('win-design-a2ui-event', (e: Event) => {
  const {
    message, // 事件消息
    respond, // 完成回调(相当于 processor 模式的 resolve)
    updateDataModel,
    getDataValue,
    getFormInstance,
    getPangoEditorInstance,
    getPangoEditorParams,
    eventInputParams,
  } = (e as CustomEvent).detail;

  const { name, type, surfaceId } = message.userAction;
  if (surfaceId !== 'my_surface') return; // ⚠️ 必须手动判断

  if (name === 'submit') {
    // 读取用户输入的数据
    const userName = getDataValue(surfaceId, '/userName');
    console.log('用户输入了:', userName);

    // 更新数据
    updateDataModel(surfaceId, '/result', '提交成功');

    respond([]); // ⚠️ 必须调用
  } else {
    respond([]); // 不处理也必须调用
  }
});

respond — 为什么必须调用?

用户点击按钮后,A2UI 会"暂停"等你处理完。respond 就是告诉 A2UI "我处理完了,你可以继续了"。

三种用法:

typescript
// 1. 不需要更新页面,传空数组即可
respond([]);

// 2. 已经用 updateDataModel 更新了数据,respond 只负责"解除暂停"
updateDataModel(surfaceId, '/result', '提交成功');
respond([]);

// 3. 不处理也必须调用
respond([]);

DANGER

不调用 respond,页面会卡住! 无论你做了什么处理,最后都必须调用一次。


eventInputParams

createSurface 消息中传入的业务参数,会在所有事件中原样返回。

传入:

json
{
  "createSurface": {
    "surfaceId": "main",
    "eventInputParams": [{ "userId": "user_001", "role": "admin" }]
  }
}

获取:

typescript
window.addEventListener('win-design-a2ui-surface-created', (e) => {
  console.log(e.detail.eventInputParams);
  // → [{ userId: 'user_001', role: 'admin' }]
});

window.addEventListener('win-design-a2ui-event', (e) => {
  console.log(e.detail.eventInputParams);
  // → 同上
});

注意事项

  1. 必须过滤 surfaceIdwindow.addEventListener 是全局的,页面有多个 A2UI 实例时,需要在回调中检查 surfaceId

  2. 必须调用 respond:用户操作事件中,无论是否处理了数据,都必须调用 respond([]),否则页面会卡住。

  3. 清理监听:组件销毁时用 window.removeEventListener 移除监听,防止内存泄漏。

  4. Vue 项目建议用 processor 方法processor.onEvent() 自动隔离多实例,不需要手动过滤 surfaceId。详见 Processor API - 事件监听


下一步