You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CKEditor5自定义属性丢失:如何保留上传图片的tmpFid属性?

解决CKEditor5图片自定义属性tmpFid随内容变更丢失的问题

问题根源

你当前的代码把模型schema扩展和转换规则注册都放在了uploadComplete事件回调内部,这会导致:

  • 编辑器初始化阶段并没有识别tmpFid属性的合法性
  • 只有第一次图片上传完成后,相关配置才会被添加,但此时编辑器的核心规则已经初始化完成
  • 当内容发生变更(比如编辑、重新渲染、切换模式)时,编辑器的schema会认为tmpFid是非法属性,从而自动清理掉

修正方案

将schema扩展和转换规则的注册逻辑移到插件的顶层(编辑器初始化时执行),仅在uploadComplete事件中保留设置属性的逻辑。

修改后的代码

export const attrPlugin = (editor: any): void => {
  // 1. 扩展模型schema,允许imageBlock和imageInline拥有tmpFid属性
  editor.model.schema.extend("imageBlock", {
    allowAttributes: "tmpFid",
  });
  editor.model.schema.extend("imageInline", {
    allowAttributes: "tmpFid",
  });

  // 2. 配置属性转换规则:视图层tmp-fid ↔ 模型层tmpFid
  // 向上转换(视图→模型)
  editor.conversion.for("upcast").attributeToAttribute({
    view: "tmp-fid",
    model: "tmpFid",
  });

  // 编辑模式向下转换(模型→视图):处理行内图片
  editor.conversion.for("editingDowncast").add((dispatcher: any) => {
    dispatcher.on(
      "attribute:tmpFid:imageInline",
      (evt: any, data: any, { writer, consumable, mapper }) => {
        if (!consumable.consume(data.item, evt.name)) {
          return;
        }
        const imageContainer = mapper.toViewElement(data.item);
        const imageElement = imageContainer.getChild(0);
        if (data.attributeNewValue !== null) {
          writer.setAttribute(
            "tmp-fid",
            data.attributeNewValue,
            imageElement
          );
        } else {
          writer.removeAttribute("tmp-fid", imageElement);
        }
      }
    );
  });

  // 输出模式向下转换(模型→视图):处理块级图片
  editor.conversion.for("downcast").add((dispatcher: any) => {
    dispatcher.on(
      "attribute:tmpFid:imageBlock",
      (evt: any, data: any, conversionApi: any) => {
        if (!conversionApi.consumable.consume(data.item, evt.name)) {
          return;
        }
        const viewWriter = conversionApi.writer;
        const figure = conversionApi.mapper.toViewElement(data.item);
        const img = figure.getChild(0);
        if (data.attributeNewValue !== null) {
          viewWriter.setAttribute("tmp-fid", data.attributeNewValue, img);
        } else {
          viewWriter.removeAttribute("tmp-fid", img);
        }
      }
    );
  });

  // 3. 上传完成时设置属性
  editor.plugins
    .get("ImageUploadEditing")
    .on("uploadComplete", (evt: any, { data, imageElement }) => {
      editor.model.change((writer: any) => {
        writer.setAttribute("tmpFid", data.tmpFid, imageElement);
      });
    });
};

关键改动说明

  • 将schema扩展和转换规则移到插件初始化时执行,确保编辑器从一开始就认可tmpFid属性的合法性
  • 保留uploadComplete事件中设置属性的逻辑,确保上传后属性能正确写入模型
  • 分离配置逻辑和业务逻辑,符合CKEditor5插件的生命周期规范

这样修改后,无论内容如何变更,编辑器都会识别tmpFid为合法属性,不会再自动删除。

内容的提问来源于stack exchange,提问作者whitesong715

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 22:12:37