向下转换 - 模型到视图
# 介绍
将模型转换为视图的过程称为向下转换。
每次需要将模型节点或属性转换为视图节点或属性时,都会发生向下转换过程。
编辑器引擎运行转换过程并使用插件注册的转换器。
# 注册转换器
要告诉引擎如何将特定的模型元素转换为视图元素,您需要使用editor.conversion.for( 'downcast' )
方法注册一个向下转换转换器,列出应该在过程中转换的元素
editor.conversion
.for( 'downcast' )
.elementToElement( {
model: 'paragraph',
view: 'p'
} );
上面的转换器将处理将每个<paragraph>
模型元素转换为<p>
视图元素。您可以在下面的代码片段中看到输入和输出。
这只是一个示例。事实上,段落支持已经由段落插件提供,因此您实际上不需要编写自己的<paragraph>
元素到<p>
元素转换。
您刚刚了解了elementToElement()
向下转换转换辅助方法!更多助手在后面的章节中进行介绍。
# 向下转换管道
CKEditor 5 引擎使用两种不同的视图:数据视图和编辑视图。
数据视图用于生成编辑器输出。此过程由数据管道控制。
另一方面,编辑视图是您打开编辑器时看到的视图。这由编辑管道控制。
之前介绍的简单代码示例同时为这两个管道注册了一个转换器。这意味着<paragraph>
模型元素将在数据视图和编辑视图中都转换为<p>
视图元素。
有时您可能想更改特定管道的转换器逻辑。例如,在编辑视图中,您可能希望在视图元素中添加一些额外的类。这种操作需要为这两个视图设置单独的转换器,与之前的示例不同,在之前的示例中,设置了一个通用的向下转换。
// dataDowncast for data pipeline
editor.conversion
.for( 'dataDowncast' )
.elementToElement( {
model: 'paragraph',
view: 'p'
} );
// editingDowncast for editing pipeline
editor.conversion
.for( 'editingDowncast' )
.elementToElement( {
model: 'paragraph',
view: {
name: 'p',
classes: 'paragraph-in-editing-view'
}
} );
# 转换文本属性
您应该已经从关于模型的章节中知道,可以将属性应用于模型文本节点。
这种文本节点属性可以转换为视图元素。
为此,您可以使用attributeToElement()
转换助手注册一个转换器
editor.conversion
.for( 'downcast' )
.attributeToElement( {
model: 'bold',
view: 'strong'
} );
上面的转换器将处理将每个bold
模型文本节点属性转换为<strong>
视图元素,如下面的代码片段所示。
粗体文本
同样,这只是一个为了简单起见而给出的示例。粗体支持实际上由基本样式插件提供,因此您不必编写自己的粗体属性到强元素转换。
# 将元素转换为元素
与前面的示例类似,您可以使用elementToElement()
转换助手将<heading>
模型元素转换为<h1>
视图元素。实现此目的的代码如下所示
editor.conversion
.for( 'downcast' )
.elementToElement( {
model: 'heading',
view: 'h1'
} );
等同于
editor.conversion
.for( 'downcast' )
.elementToElement( {
model: 'heading',
view: ( modelElement, { writer } ) => {
return writer.createContainerElement(
'h1'
);
}
} );
您之前已经了解到view
属性可以是简单的字符串或对象。上面的示例表明,还可以定义一个自定义回调函数来返回创建的元素。这种转换的效果可以在下面的代码片段中观察到
<heading>
元素在您可以设置视图中的标题级别时最有意义。
在上一章中,您已经了解到可以将属性应用于文本节点。也可以向元素添加属性,例如在以下示例中
editor.conversion
.for( 'downcast' )
.elementToElement( {
model: {
name: 'heading',
attributes: [ 'level' ]
},
view: ( modelElement, { writer } ) => {
return writer.createContainerElement(
'h' + modelElement.getAttribute( 'level' )
);
}
} );
从现在开始,每次级别属性更新时,整个<heading>
元素将转换为<h[level]>
元素(例如<h1>
、<h2>
等)。
您可以使用以下示例查看它的实际效果。使用下拉菜单更改模型中的标题级别,并查看视图元素如何通过转换器更新
同样,这只是一个示例。标题支持实际上由标题功能提供,因此您不必编写自己的<heading level="1">
到<h1>
元素转换。
# 将元素转换为结构
有时您可能希望将一个单个模型元素转换为一个更复杂的视图结构,该结构包含一个具有子元素的单个视图元素。
您可以使用elementToStructure()
转换助手来实现此目的
editor.conversion
.for( 'downcast' ).elementToStructure( {
model: 'myElement',
view: ( modelElement, { writer } ) => {
return writer.createContainerElement( 'div', { class: 'wrapper' }, [
writer.createContainerElement( 'div', { class: 'inner-wrapper' }, [
writer.createSlot()
] )
] );
}
} );
上面的转换器将把所有<myElement>
模型元素转换为<div class="wrapper"><div class="inner-wrapper"><p>...</p></div></div>
结构,如下所示
示例结构
使用您自己的自定义模型元素需要首先在模式中定义它。
对于编辑器用户来说,与复杂结构交互的最佳方式是作为独立的实体,并保持完整,例如,在复制、粘贴和编辑时。CKEditor 5 通过小部件 API允许这样做。如果您想了解如何在elementToStructure()
之上使用它,请务必查看实现块小部件教程。
# 进一步阅读
如果您想了解有关本指南中提到的向下转换助手的更多信息,我们已为您总结了这些助手,并附带完整的描述和示例。我们还建议您查看向上转换转换指南,并了解如何将编辑器输入的原始数据转换为活动的模型状态。
我们每天都在努力使我们的文档保持完整。您是否发现过时信息?是否缺少内容?请通过我们的问题跟踪器报告。
随着 42.0.0 版本的发布,我们重新编写了大部分文档,以反映新的导入路径和功能。感谢您提供反馈,帮助我们确保文档的准确性和完整性。