感谢您描述您的情况。目前,了解开发人员如何使用编辑器以及您的期望对我们来说意义重大。
不幸的是,这看起来是一个非常复杂的功能。它看起来也需要自定义 UI(编辑链接 url 和图像 src——除非它们在添加到编辑器后没有改变)。您似乎在为两个问题而苦苦挣扎:
首先,回答您的问题- 将它们用于和元素EditableElement
似乎是正确的。h3
p
但是,如此复杂的功能需要自定义转换器。转换器构建器(您使用的)专门用于简单的情况,例如元素到元素的转换,或属性到属性的转换。
在漂亮的 API 背后,构建转换器是一个函数工厂,它创建一个或多个函数。然后将这些作为回调添加到ModelConversionDispatcher
(这editor.editing.modelToView
是一个实例)。ModelConversionDispatcher
在转换期间触发一系列事件,这是将模型中的更改转换为视图的过程。
正如我所提到的,您必须自己编写这些转换函数。
由于这个主题太大而无法提供详细而彻底的答案,因此我将简要介绍您应该感兴趣的内容。不幸的是,目前还没有关于从头开始创建自定义转换器的指南。这是一个非常广泛的主题。
首先,让我解释一下你的大部分问题来自哪里。如您所知,编辑器具有三层:模型(数据)、视图(类 DOM 结构)和 DOM。模型被转换为视图,视图被渲染为 DOM。另外,当你加载数据时,DOM 被转换为视图,视图被转换为模型。这就是为什么您需要为您的功能提供模型到视图转换器和视图到模型转换器的原因。
这个难题的重要部分是engine.conversion.Mapper
。它的作用是将元素和位置从模型映射到视图。正如您可能已经看到的那样,模型可能与视图完全不同。它们之间的正确位置映射是关键。当您在插入符号位置(在 DOM 中)键入字母时,该位置会映射到模型,并且字母会插入模型中,然后才转换回视图和 DOM。如果视图到模型的位置转换错误,您将无法在该位置键入或真正执行任何操作。
Mapper
本身就很简单。它所需要的只是指定哪些视图元素绑定到哪些模型元素。例如,在模型中您可能有:
<listItem type="bulleted" indent="0">Foo</listItem>
<listItem type="bulleted" indent="1">Bar</listItem>
在视图中,您有:
<ul>
<li>
Foo
<ul>
<li>Bar</li>
</ul>
</li>
</ul>
如果映射器知道 firstlistItem
与 first 绑定,<li>
并且 secondlistItem
与 second 绑定<li>
,则它能够正确转换位置。
回到你的情况。每个转换器必须为Mapper
. 由于您使用了转换器构建器,因此由它构建的转换器已经执行此操作。但它们很简单,所以当您提供时:
buildModelConverter().for(editing.modelToView)
.fromElement('myElement')
.toElement(new ContainerElement('div', {}, [new EditableElement('h4')]));
假设,那myElement
与<div>
. 所以里面写的任何东西都<div>
将直接进入myElement
,然后将在开头呈现myElement
:
<div>
<h4></h4>
</div>
假设你刚刚写了x
at <h4>
,那个位置会被映射到模型中的myElement
offset 0
,然后渲染到开头的 view 上<div>
。
模型:
<myElement>x</myElement>
看法:
<div>x<h4></h4></div>
如您所见,在您的情况下,它<h4>
应该与myElement
.
目前,我们正处于重构阶段。目标之一是为转换器制造商提供更多实用功能。这些实用程序之一是具有包装器元素的元素的转换器,例如上面的“div + h4”案例。这也是图像特征的一个例子。图像<image>
在模型中表示,但它<figure><img /></figure>
在视图中。你可以看看ckeditor5-image
这些转换器现在的样子。我们想简化它们。
不幸的是,您的实际情况更加复杂,因为您内部有多个元素。CKE5 架构应该能够处理您的情况,但您必须了解,如果没有适当的指南,这几乎是不可能编写的。
如果你想修补,你应该学习 ckeditor5-image
repo。这并不容易,但这是最好的方法。Image
插件与ImageCaption
您的情况非常相似。
模型:
<image alt="x" src="y">
<caption>Foo</caption>
</image>
看法:
<figure class="image">
<img alt="x" src="y" />
<figcaption>Foo</caption>
</figure>
在您的情况下,我会在这些线之间的某处看到模型:
<rankItem imageSrc="x" linkUrl="y">
<rankTitle>Foo</rankTitle>
<rankNotes>Bar</rankNotes>
</rankItem>
而且我会让视图更重一些,但编写转换器会更容易:
<li contenteditable="false">
<a href="y">
<img src="x" />
<span class="data">
<span class="title" contenteditable="true">Foo</span>
<span class="notes" contenteditable="true">Bar</span>
</span>
</a>
</li>
rankTitle
和rankNotes
- 以caption
元素 ( )为基础ckeditor5-image/src/imagecaption/imagecaptionengine.js
。
For rankItem
- 基于image
元素 ( ckeditor5-image/src/image/
)。
再一次 - 请记住,我们正在简化所有这些。我们希望人们编写自己的功能,即使是像您这样复杂的功能。但是,我们现在知道它有多复杂。这就是目前没有文档的原因——我们正在寻求改变和简化事情。
Link
最后 - 您可以使用转换器构建器构建的插件和元素更简单地创建该排名列表:
rankList
-> <ol class="rank">
,
rankItem
-> <li>
,
rankImage
-> <img />
,
rankNotes
-> <span class="notes">
,
rankTitle
-> <span class="title">
。
但是,由于整个结构是可编辑的,因此可能会搞砸。
模型:
<rankList>
<rankItem>
<rankImage linkHref="" />
<rankTitle>Foo</rankTitle>
<rankNotes>Bar</rankNotes>
</rankItem>
...
</rankList>
其中“Foo”和“Bar”也linkHref
设置了属性。
看法:
<ol class="rank">
<li>
<a href=""><img src="" /></a>
<span class="title"><a href="">Title</a></span>
<span class="notes"><a href="">Foo</a></span>
</li>
...
</ol>
像这样的东西,虽然远非完美,但只要我们在重构之前和编写指南之前,应该更容易编写。
当然,您还必须提供视图到模型的转换器。您可能想自己编写它们(看看ckeditor5-list/src/converters.js
viewModelConverter()
——尽管您的会更容易,因为它是扁平的,而不是嵌套列表)。或者您可以通过转换器生成器生成它们。
也许可以使用上面的方法(更简单)但使用contentEditable
属性来控制结构。rankList
必须转换为<ol>
with contentEditable="false"
。例如,也许您可以以某种方式使用toWidget
更好的选择处理。rankNotes
并且rankTitle
必须使用contentEditable="true"
(也许使用toWidgetEditable()
)转换为元素。