携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第2天,点击查看活动详情
概览
相对于早期的富文本编辑器,CKEditor更进一步,提供了一套数据转换机制,通过数据模型来进行视图的渲染,用户的操作直接作用数据模型,而不再是直接进行dom的操作。
数据模型转化势必是双向的:Model转化为View、View转化为Model。而在CKEditor5中,用来映射视图元素的模型元素称为Schema,而对于模型元素和视图元素之间相互转化过程我们称为Conversion。
-
Conversion:分为两种:downcast 和 upcast。其中,对于downcast可以细分为两种:Data downcast 和 Editing downcast,分别用于处理创建和编辑过程的转化。
-
Schema:,包含 block 、$text , 分别指代根节点、块元素、普通文本。
视图转换为模型(upcast)
CKEditor5提供了向上转化的通道——upcast。每次进行初始化的时候,都会通过upcast将数据转换为模型。
upcast转化的过程中,定义了 UpcastWriter 来操作视图树,约定了 elementToElement、elementToAttribute、attributeToAttribute 三种转化规则来处理Schema,将视图元素转化为模型元素。
视图元素划分为 ContainerElement、UIElement、Emptyelement、Aattributeelement、EditableElement、Text 等几种类型,分别对应不同功能的容器元素、UI元素、空元素、属性元素、可编辑元素、文本。
1. elementToElement
elementToElement实现将视图元素(div、p)转换为相应的模型元素。
editor.conversion.for( 'upcast' ).elementToElement( {
view: 'p',
model: 'example'
} );
这是一个将视图元素div转化为模型元素example的例子,至于example的具体属性定义在example的Schema中:
2. elementToAttribute
elementToAttribute实现将内联文本格式视图元素(strong、i等)转换为模型元素上的属性。
editor.conversion
.for( 'upcast' )
.elementToAttribute( {
view: 'strong',
model: 'bold'
} );
这是一个将加粗文本转换为paragraph模型元素上的bold属性的示例:
3. attributeToAttribute
attributeToAttributen实现将视图元素的属性(src、href等)转换到模型元素上的属性。
editor.conversion
.for( 'upcast' )
.attributeToAttribute( {
view: 'src'
model: 'source'
} );
这是一个将视图元素img的src属性转换为模型元素image的source属性的示例:
模型转化为视图(downcast)
CKEditor也提供了向下转化的通道——downcast,用来将模型转换为视图。大家进行视图编辑的时候,都会直接应用于模型,然后通过downcast转化为视图,间接来更新视图内容,而不是想象中的直接操作dom;当通过editor.getData() 获取编辑器内容的时候,触发的也是downcast。
在视图转换的过程中,我们通过定义了DowncastWriter(不同于UpcatWriter)来创建视图元素,约定了elementToElement、attributeToElement、attributeToAttribute、elementToStructure规则来转化Schema,并提供了几种创建视图容器的方法createContainerElement、createUIElement、createEmptyElement、createAttributeElement、createEditableElement、createText(与upcase中处理的视图元素相对应);downcase中一种额外的方法createSlot来创建可插入内容的容器元素。
1. elementToElement
elementToElement实现将模型元素转换为视图元素(div、p等),这应该是最常用的转换规则了。
editor.conversion
.for( 'downcast' )
.elementToElement( {
model: 'paragraph',
view: 'p'
} );
这是一个将模型元素paragraph转化为视图元素p的例子,至于paragraph的具体属性定义在paragraph的Schema中:
2. attributeToElement
elementToAttribute实现将模型元素上的属性转换为内联文本格式视图元素(strong、i等)。
editor.conversion
.for( 'downcast' )
.attributeToElement( {
model: 'bold',
view: 'strong'
} );
这是一个将paragraph模型元素上的bold属性转换为加粗文本示例:
3. attributeToAttribute
attributeToAttributen实现将视图元素的属性(src、href等)转换到模型元素上的属性。
editor.conversion
.for( 'downcast' )
.attributeToAttribute( {
model: 'source',
view: 'src',
} );
这是一个将模型元素image的source属性转换为视图元素img的src属性的示例:
4. elementToStructure
elementToStructure实现复杂的模型元素的转换,其余的转化方式跟upcast都存在相互对应的,唯有这个方法是downcast独有的。这种视图元素是由视图元素及其子元素组成的,需要跟createSlot组合使用来创建父容器。
editor.conversion
.for( 'downcast' ).elementToStructure( {
model: 'container',
view: ( modelElement, { writer } ) => {
return writer.createContainerElement( 'div', { class: 'wrapper' }, [
writer.createContainerElement( 'div', { class: 'inner-wrapper' }, [
writer.createSlot()
] )
] );
}
} );
这是一个将模型元素container转换为嵌套的容器元素的示例(其中,视图元素p是大家进行编辑的时候插入的):