事件系统

← 核心 API | 完整示例 →

OnlyOffice Embed SDK 使用 EventBus 进行跨模块事件通信。

事件类型

import { ONLYOFFICE_EVENT_KEYS } from "@/components/onlyoffice-web-comp";

ONLYOFFICE_EVENT_KEYS.SAVE_DOCUMENT   // 'saveDocument' - 文档保存/导出完成
ONLYOFFICE_EVENT_KEYS.DOCUMENT_READY  // 'documentReady' - 文档准备就绪
ONLYOFFICE_EVENT_KEYS.LOADING_CHANGE  // 'loadingChange' - Loading 状态变化
ONLYOFFICE_EVENT_KEYS.ONSAVE          // 'onSave' - 编辑器 onSave 流程完成(轻量通知)
ONLYOFFICE_EVENT_KEYS.OFFICE_XML_SIZE_LIMIT_EXCEEDED // 'officeXmlSizeLimitExceeded' - Office XML 解压体积超过限制

事件说明

事件触发时机典型用途
SAVE_DOCUMENT导出/保存完成,export() 等待此事件获取 binData、上传服务端
DOCUMENT_READY编辑器 iframe 内文档加载完成初始化批注/修订、隐藏骨架屏
LOADING_CHANGEsetReadOnlyexport 等长操作全局 Loading UI
ONSAVE保存回调已通知编辑器(asc_onSaveCallback 之后)提示「已保存」,无需 binData
OFFICE_XML_SIZE_LIMIT_EXCEEDED开启 officeXmlEvent 后,Office ZIP 内 XML 包内容解压后超过阈值,x2t 转换前拦截上报风险文件、自定义错误提示

SAVE_DOCUMENTONSAVE 在一次保存流程中都会触发:前者携带完整二进制数据,后者仅携带 fileNameinstanceId

监听事件

import {
  onlyofficeEventbus,
  ONLYOFFICE_EVENT_KEYS,
} from "@/components/onlyoffice-web-comp";

onlyofficeEventbus.on(ONLYOFFICE_EVENT_KEYS.DOCUMENT_READY, (data) => {
  console.log("文档已准备就绪:", data.fileName);
  // data: { fileName, fileType, instanceId? }
});

onlyofficeEventbus.on(ONLYOFFICE_EVENT_KEYS.SAVE_DOCUMENT, (data) => {
  console.log("文档已保存:", data.fileName);
  // data: { fileName, fileType, binData, instanceId, media? }

  if (data.instanceId === manager.getEditor().getInstanceId()) {
    // 多实例:仅处理当前实例
  }
});

onlyofficeEventbus.on(ONLYOFFICE_EVENT_KEYS.ONSAVE, (data) => {
  console.log("保存流程完成:", data.fileName);
  // data: { fileName, instanceId }
});

onlyofficeEventbus.on(ONLYOFFICE_EVENT_KEYS.LOADING_CHANGE, (data) => {
  setLoading(data.loading);
});

onlyofficeEventbus.on(
  ONLYOFFICE_EVENT_KEYS.OFFICE_XML_SIZE_LIMIT_EXCEEDED,
  (data) => {
    console.warn(data.errorDescription, data.fileName);
    // data: { fileName, fileType, errorDescription, xmlBytes, limitBytes, entryCount, instanceId, containerId }
  },
);

通过 OnlyOfficeManager 监听 Loading

const unsubscribe = manager.onLoadingChange(({ loading }) => {
  setLoading(loading);
});

// 组件卸载时
unsubscribe();

等待事件

waitFor 返回 Promise,第二个参数为超时毫秒数,默认 30000

const readyData = await onlyofficeEventbus.waitFor(
  ONLYOFFICE_EVENT_KEYS.DOCUMENT_READY,
  10000,
);

const saveData = await onlyofficeEventbus.waitFor(
  ONLYOFFICE_EVENT_KEYS.SAVE_DOCUMENT,
  10000,
);

相关常量:

常量说明
waitFor 默认超时30000 ms未传第二参数时
READONLY_SWITCH_MIN_DELAY_MS200 ms只读切换时 loading 最短展示时长,防闪烁

Loading 状态管理

LOADING_CHANGE 在导出、只读切换等操作时自动触发:

import { useEffect, useState } from "react";
import {
  onlyofficeEventbus,
  ONLYOFFICE_EVENT_KEYS,
} from "@/components/onlyoffice-web-comp";

function EditorPage() {
  const [loading, setLoading] = useState(false);

  useEffect(() => {
    const handleLoadingChange = (data: { loading: boolean }) => {
      setLoading(data.loading);
    };

    onlyofficeEventbus.on(
      ONLYOFFICE_EVENT_KEYS.LOADING_CHANGE,
      handleLoadingChange,
    );

    return () => {
      onlyofficeEventbus.off(
        ONLYOFFICE_EVENT_KEYS.LOADING_CHANGE,
        handleLoadingChange,
      );
    };
  }, []);

  return <div>{loading && <Loading />}</div>;
}

注意: editorManager.setReadOnly()export() 会触发 LOADING_CHANGEexport() 在只读模式下不经过编辑器保存,通常不会拉长 loading。

SDK 层回调(与 EventBus 互补)

编辑器 iframe 内的 Word API 支持 asc_registerCallback,通过 EditorManager.subscribe() 封装。常用回调名见 AscWordApiMethod,例如:

  • asc_onAddComment / asc_onChangeCommentData / asc_onRemoveComment — 批注变化
  • asc_onShowRevisionsChange — 修订列表变化
  • asc_onDocumentModifiedChanged — 文档修改状态

详见 批注修订与 Word API

取消监听

const handler = (data: unknown) => {
  console.log("事件触发:", data);
};

onlyofficeEventbus.on(ONLYOFFICE_EVENT_KEYS.DOCUMENT_READY, handler);
onlyofficeEventbus.off(ONLYOFFICE_EVENT_KEYS.DOCUMENT_READY, handler);

EditorManager.subscribe() 返回的卸载函数用于取消 SDK 回调,与 EventBus 的 off 相互独立。