多子文档

文档与房间名称

大多数 Yjs 连接提供者(包括 y-websocket 提供者)都使用一个称为房间名称(room-names)的概念。客户端会向 Hocuspocus 传递一个房间名称参数,后者会用来识别当前正在编辑的文档。在本教程中,我们将把房间名称称为文档名称。

在真实的应用中,您很可能会使用实体名称和唯一 ID。对于 CMS,示例如下:

const documentName = "page.140";

现在,您可以轻松拆分它以分别获得所需的信息:

const [entityType, entityID] = documentName.split(".");

console.log(entityType); // 输出 "page"
console.log(entityID); // 输出 "140"

这只是建议,当然您可以随意命名您的文档!

嵌套文档

介绍

我们目前正在评估子文档的反馈,但尚未实现支持。

在很多情况下,您可以使用 Yjs 的不同 fragments 代替子文档。因此,如果您想为一篇博客文章使用 title/content,您可以创建一个 yDoc,并使用不同的编辑器(或其他任何东西)分别绑定到不同的 fragment,如下所示:

const ydoc = new Y.Doc();

const titleEditor = new Editor({
  extensions: [
    Collaboration.configure({
      document: this.ydoc,
      field: "title",
    }),
  ],
})

const bodyEditor = new Editor({
  extensions: [
    Collaboration.configure({
      document: this.ydoc,
      field: "body",
    }),
  ],
})

当使用多个字段时,您可以简单地将不同的文档合并到给定的文档中:

import { readFileSync } from "fs";
import { Server } from "@hocuspocus/server";
import { TiptapTransformer } from "@hocuspocus/transformer";
import Document from "@tiptap/extension-document";
import Paragraph from "@tiptap/extension-paragraph";
import Text from "@tiptap/extension-text";

const generateSampleProsemirrorJson = (text: string) => {
  return {
    type: "doc",
    content: [
      {
        type: "paragraph",
        content: [
          {
            type: "text",
            text,
          },
        ],
      },
    ],
  };
};

const server = new Server({
  async onLoadDocument(data) {
    // 仅当主存储中没有设置时才导入
    if (data.document.isEmpty("default")) {
      // 获取 'default' 字段的 Y-Doc …
      const defaultField = TiptapTransformer.toYdoc(
        generateSampleProsemirrorJson("What is love?"),
        "default",
        [(Document, Paragraph, Text)]
      );
      // … 并将它合并到给定的文档中
      data.document.merge(defaultField);
    }
    if (data.document.isEmpty("secondary")) {
      // 获取 'secondary' 字段的 Y-Doc …
      const secondaryField = TiptapTransformer.toYdoc(
        generateSampleProsemirrorJson("Baby don't hurt me…"),
        "secondary",
        [(Document, Paragraph, Text)]
      );
      // … 并将它合并到给定的文档中
      data.document.merge(secondaryField);
    }
  },
});
server.listen();