跳到正文
QuireKit
Classic 文档
Alpha · API 持续演进
Classic 开发查看 Markdown ↗

保存、打开与文件转换

为 Classic 接入未保存状态、版本化 JSON 和 DOCX 服务,并处理保存失败与格式损失。

Classic 不会自动把正文写进你的数据库。应用负责保存位置、文档身份和未保存提示;产品提供当前内容及已安装的格式服务。本页从已挂载的 instance 开始,创建方式见快速接入。

1. 记录真正的正文变化

产品插件的 onUpdate 还会响应选区和界面刷新,不适合直接当作“正文已修改”。在插件的 onMount 订阅当前 Core 的 update,比较前后文档身份,在 onUnmount 解除订阅。结构更新重建 Core 后会重新绑定;语言、只读和内置主题更新保留原订阅。

classic/persistence/observer.tsts

创建时把 createClassicDraftObserver(() => { dirty = true }) 加入实例的 plugins。dirty 是应用自己的状态;一个插件对象只交给一个实例。例程不在每次变化时序列化全文,切换只读也不会误报正文修改。显式使用 emitUpdate: false 的恢复流程应由宿主建立新的已保存基线。

2. 保存一个确定的版本

instance.getJSON() 读取当前规范内容。备份还应带上自己的版本、模型和文档 ID;文档名称可通过 instance.setDocumentName(name) 更新,名称由应用另行持久化,不包含在 getJSON() 中。

下面的 Word 草稿例程先捕获内容,再等待存储确认。返回 true 才表示当前页面仍停留在刚保存的版本;返回 false 表示这次写入完成了,但期间发生了编辑、重挂载或退出,不应清除未保存提示。

classic/persistence/save.tsts

repository.write(source) 由你连接接口或本地存储,失败应拒绝 Promise。保存按钮在请求期间禁用,或由 repository 串行写同一文档;返回值只保护界面的保存状态,不能阻止服务端并发请求倒序覆盖。多用户编辑还需要版本冲突协议。这个例程只保存 JSON,图片字节仍需持久媒体服务。

3. 打开 JSON 备份

先读取原文件,检查模型、版本、节点、标记、属性和 Schema,再提交。完整校验顺序见内容校验与文件操作。损坏文件不能替换当前草稿。

内置 json 服务读取原生规范文档 JSON,并通过相同的提交边界严格替换;它不识别本页例程带有版本、模型和 content 包装的业务备份。业务备份先由应用解包校验,再按下面的流程打开。

打开另一份业务文档时,先处理当前未保存修改,再建立新会话边界:

提交已经校验的备份ts

这会销毁旧 Core 并用新正文挂载;原撤销历史不会保留。插件通过挂载钩子重新订阅。应用同步切换文档 ID、存储键和已保存基线,并取消旧文档的保存任务。不要在输入事件中反复传入 document。

只恢复当前会话正文时,可以使用 Core 的 replaceDocument(),它连同顶层属性替换且本次不计入历史;这与创建新会话的生命周期不同。

4. 装配 DOCX / DOTX 服务

createClassicWordDocxPlugin() 默认注册 docx、dotx 两个服务。它们与 Word preset 配合,通过 plugins 安装一次。预设本身不代表这些服务已经注册。

在快速接入的 plugins 中安装ts

showConversionReport 是你的界面函数:区分解析警告与内容近似、保留或丢失的诊断。导入成功不代表完全无损;不符合 Schema 的块可能被降级为纯文本并报告 schema-invalid-block。不要把一次成功返回显示成“格式完全保留”。配置见 DOCX 插件参考。

5. 调用文件服务

传入文件字节并取得导出产物ts

file 是宿主选择的 File。DOCX 需要字节,不能传文本;DOTX 使用 dotx 服务 ID。导出返回 data、fileName、mimeType,宿主负责下载或上传,成功生成文件不等于数据库已保存。服务不存在、没有对应操作或产品未挂载时,调用会拒绝 Promise;转换失败也需要捕获并展示。

6. 取消与防止迟到覆盖

importDocument() 为每次调用捕获当前 Core 与正文版本。新的导入、正文修改(包括修改后撤销)、只读配置更新、卸载或销毁,会让尚未提交的旧导入失效。移动光标不使正文版本过期。官方 DOCX 服务在最后的同步提交边界复核这些条件,过期时拒绝为 AbortError,保留当前正文与名称,也不发成功转换报告。

宿主取消一次打开操作ts

在读取文件字节前建立 controller;选择新文件时先取消上一次,防止旧文件的 arrayBuffer() 迟到后才启动导入。Abort 可以及时结束调用方等待,但底层不支持取消的 codec 仍可能完成内部解析;最终提交仍被拦截。已经提交的写入不能通过随后 abort 撤销。

只读会在导入入口与提交前各检查一次,应用还需检查业务授权。若要打开完全不同的业务文档,仍需处理未保存修改、存储键和会话边界;导入不是文档管理系统。

7. 自定义 import 的迁移

自定义服务先解析和校验,再在 context.commit(() => editor.commands.replaceDocument(...)) 中执行一次同步命令,并在提交后报告成功。不要把 async 回调传给 commit,也不要在 commit 外直接写正文。旧插件若绕过这个合同直接调用命令,运行时无法回滚其任意副作用;应升级插件后再依赖过期保护。完整上下文见 Classic API。

导出是否捕获点击时快照由服务实现决定;官方 DOCX 服务会捕获开始时的正文。导入图片的暂存与失败清理见持久媒体。自己开发 Core 产品时,仍使用解析、校验、提交的宿主流程。

实例和配置的完整字段见Classic 实例与配置参考。

QuireKitQuireKit · Core、插件与 Classic 文档