Contribute to this guide

guide模型和模式

# 编辑器

编辑器有几种不同的类型。虽然它们在视觉上看起来不同,但它们在幕后是相似的,并且包含两个部分:

  • 编辑引擎,
  • 编辑 UI。

在本教程的本章和接下来的几章中,您将了解编辑引擎,它负责读取、维护和输出编辑器状态,以及所有在幕后为编辑器提供动力的其他内容。

稍后您还将了解编辑 UI,但现在,您只需要知道它就是用户看到的并与其交互的界面。

# 模型

编辑引擎中第一个也是最重要的部分是模型。模型是类似 HTML 的结构,它表示编辑器的内容。当调用editor.setData() 方法时,作为参数传递的 HTML 将被转换为模型。然后,当调用editor.getData() 方法时,模型将被转换回 HTML。

模型与 HTML 之间的一个主要区别是,在模型中,文本和元素都可以具有属性。

让我们看看模型与 HTML 相比如何。

Hello world!

# 模式

您不能将任何您想要的内容放在文档模型中。至少在您更新模式之前是这样。模式定义了哪些内容是允许的以及在何处允许、哪些属性允许用于某些节点、哪些内容是不允许的,等等。

模式决定了诸如给定元素是否可以包含在块引用中,或者是否在选定的内容上启用粗体按钮等内容。

# 扩展模型以支持文本高亮

有了这些信息,我们该如何添加对高亮的支持?我们需要处理两件事:

  1. 我们需要在模型中以某种方式跟踪文本的哪些部分被高亮显示。
  2. 由于 HTML 使用 <mark> 元素来进行高亮显示,因此我们希望能够将其转换为模型并从模型转换回来。

# 扩展模式

正如我们之前所学到的,模型中的文本节点可以具有属性。我们还看到,斜体、粗体和下划线文本不像 HTML 中那样使用元素,而是使用文本属性。由于高亮显示的工作方式与这三种文本样式相同,因此让我们采用相同的路径。

让我们扩展 $text 节点以允许一个名为 highlight 的新属性。将以下代码添加到 src/plugin.jsHighlight 函数的末尾:

editor.model.schema.extend( '$text', {
    allowAttributes: 'highlight'
} );

# 转换 HTML 元素

现在我们能够将 highlight 属性添加到文本部分了,让我们使 <mark> HTML 元素能够转换为模型的 highlight 属性,反之亦然。将以下代码添加到 src/plugin.jsHighlight 函数的末尾:

editor.conversion.attributeToElement( {
    model: 'highlight',
    view: 'mark'
} );

为什么当我们想要将 <mark> HTML 元素转换为 highlight 模型 属性时,该方法被命名为 attributeToElement()?难道不应该反过来吗?

对于编辑器来说,模型是最重要的状态,而 HTML 只是输入和输出。从它的角度来看,角色是相反的 - 它具有 highlight 属性,它对应于 HTML 中的 <mark> 元素。当我们深入研究下一章中的数据转换时,您将看到这种模式重复出现。

# 测试更改

让我们测试一下我们的更改。在浏览器中打开控制台,并运行以下代码:

editor.setData( '<p>Hello <mark>world</mark>!</p>' );

如果一切顺利,world 这个词应该在编辑器中被高亮显示。

# CKEditor 检查器

让我们检查一下编辑器以验证模式和模型。打开 src/main.js 文件,并安装CKEditor 检查器

// Import inspector.
import CKEditorInspector from '@ckeditor/ckeditor5-inspector';

// Add this at the bottom of the file to inspect the editor.
CKEditorInspector.attach(editor);

当页面刷新后,您应该看到 CKEditor 的调试面板。转到 Schema 选项卡,然后单击 $text 元素。在右侧的 Allowed Attributes 部分下,您应该看到 highlight:true

转到 Model 选项卡,并在控制台中重新运行以下代码:

editor.setData( '<p>Hello <mark>world</mark>!</p>' );

注意模型是如何改变的,以及 highlight 属性是如何附加到 "world" 字符串上的。

您还可以转到 View 选项卡,查看 highlight 属性是如何转换为 <mark> 元素的。

我们将在插件开发的下一阶段使用此工具。

# 下一步

如果您想了解更多有关编辑引擎的信息,请参阅编辑引擎 文档。

否则,请转到下一章,您将了解有关数据转换的更多信息以及当我们调用 attributeToElement() 方法时真正发生了什么。