向下转换助手 - 模型到视图转换
本文列出了向下转换中可用的所有编辑器助手。
# 元素到元素转换助手
将模型元素转换为视图元素是转换最常见的情况。它用于创建我们称之为“容器元素”的视图元素,例如<p>
或<h1>
。
使用elementToElement()
助手时,单个模型元素将被转换为单个视图元素。此模型元素的子元素需要定义自己的转换器,引擎将递归地转换它们并将它们插入到创建的视图元素中。
# 基本元素到元素转换
如果你想将模型元素转换为简单的视图元素,没有任何额外的属性,只需通过转换器提供它们的名称,如以下示例所示
editor.conversion
.for( 'downcast' )
.elementToElement( {
model: 'paragraphSeparator',
view: 'hr'
} );
# 使用视图元素定义
有时你可能需要输出具有某些属性的视图元素,例如类名。为了实现这一点,你可以在view
属性中提供一个元素定义
editor.conversion
.for( 'downcast' )
.elementToElement( {
model: 'fancyParagraph',
view: {
name: 'p',
classes: 'fancy'
}
} );
查看ElementDefinition 文档以了解更多详细信息。
# 使用回调创建视图元素
使用回调编写上一节中转换器的另一种方法如下所示
editor.conversion
.for( 'downcast' )
.elementToElement( {
model: 'fancyParagraph',
view: ( modelElement, { writer } ) => {
return writer.createContainerElement(
'p', { class: 'fancy' }
);
}
} );
这里,视图回调的第二个参数是DowncastConversionApi对象。它包含许多在编写更复杂的转换器时可能会有用的属性和方法。
回调应该返回单个容器元素。此元素不应包含任何子元素,除了 UI 元素。如果你想创建更丰富的结构,请使用elementToStructure()
方法。
# 处理具有属性的模型元素
如果视图元素不仅依赖于模型元素本身,还依赖于它的属性,则需要在model
属性中指定这些属性。
editor.conversion
.for( 'downcast' )
.elementToElement( {
model: {
name: 'heading',
attributes: [ 'level' ]
},
view: ( modelElement, { writer } ) => {
return writer.createContainerElement(
'h' + modelElement.getAttribute( 'level' )
);
}
} );
如果你忘记指定这些属性,转换器仍然可以用于插入模型元素部分,但它不会处理属性值的任何更改。
# 更改转换器优先级
如果已经存在具有重叠model
模式的其他转换器,你可以优先考虑你的转换器来覆盖它们。为此,请使用converterPriority
属性
editor.conversion
.for( 'downcast' )
.elementToElement( {
model: 'userComment',
view: 'div'
} );
editor.conversion
.for( 'downcast' )
.elementToElement( {
model: 'userComment',
view: 'article',
converterPriority: 'high'
} );
在上面的示例中,第一个转换器没有显式设置优先级,因此它假设默认优先级,即normal
。第二个转换器通过将优先级设置为high
来覆盖它。同时使用这两个转换器将导致<userComment>
元素被转换为<article>
元素。
这个解决方案也可能很方便,如果你想让你的转换器在给定元素的其他转换器不存在时充当后备(例如,插件尚未加载)。可以通过将converterProperty
设置为low
轻松实现。
# 元素到结构转换助手
将单个模型元素转换为多个视图元素(视图元素的结构)。
# 处理空模型元素
要将单个模型元素horizontalLine
转换为以下结构
<div class="horizontal-line">
<hr />
</div>
你可以使用类似于此的转换器
editor.conversion
.for( 'downcast' )
.elementToStructure( {
model: 'horizontalLine',
view: ( modelElement, { writer } ) => {
return writer.createContainerElement( 'div', { class: 'horizontal-line' }, [
writer.createEmptyElement( 'hr' )
] );
}
} );
请注意,在这个示例中,我们创建了两个元素,这无法通过使用前面提到的elementToElement()
助手来实现。
对于编辑器用户来说,与复杂结构交互的最佳方式是作为独立实体进行交互,并在复制、粘贴和编辑时保持完整。CKEditor 5 通过小部件 API允许这样做。如果你想了解如何在elementToStructure()
之上使用它,请务必查看实现块小部件教程。
# 处理模型元素的子元素
上面的示例使用了一个空模型元素。如果你的模型元素可能包含子元素,则需要指定这些子元素在视图中的放置位置。为此,请使用writer.createSlot()
助手。
editor.conversion
.for( 'downcast' )
.elementToStructure( {
model: 'wrappedParagraph',
view: ( modelElement, conversionApi ) => {
const { writer } = conversionApi;
const paragraphViewElement = writer.createContainerElement( 'p', {}, [
writer.createSlot()
] );
return writer.createContainerElement( 'div', { class: 'wrapper' }, [
paragraphViewElement
] );
}
} );
对于编辑器用户来说,与复杂结构交互的最佳方式是作为独立实体进行交互,并在复制、粘贴和编辑时保持完整。CKEditor 5 通过小部件 API允许这样做。如果你想了解如何在elementToStructure()
之上使用它,请务必查看实现块小部件教程。
# 属性到元素转换助手
属性到元素转换用于创建格式化视图元素,例如<b>
或<span style="font-family: ...">
(我们称之为属性元素)。在这种情况下,我们不转换模型元素,而是转换文本节点的属性。需要注意的是,文本格式,如粗体或字体大小,应该在模型中表示为文本节点属性。
一般来说,模型没有实现“内联元素”的概念(按照 CSS 定义)。内联元素唯一可以使用的场景是自包含对象,例如软换行(<br>
)或内联图像。
# 基本文本属性到模型转换
editor.conversion
.for( 'downcast' )
.attributeToElement( {
model: 'bold',
view: 'strong'
} );
模型文本节点"CKEditor 5"
具有bold
属性将成为视图中的<strong>"CKEditor 5"</strong>
。
# 使用视图元素定义
你可能希望输出一个具有更多属性的视图元素,例如类名。为了实现这一点,你可以在view
属性中提供一个元素定义
editor.conversion
.for( 'downcast' )
.attributeToElement( {
model: 'invert',
view: {
name: 'span',
classes: [ 'font-light', 'bg-dark' ]
}
} );
查看ElementDefinition 文档以了解更多详细信息。
# 使用回调创建视图元素
你也可以通过回调生成视图元素。这种方法在视图元素依赖于模型属性的值时很有用。
editor.conversion
.for( 'downcast' )
.attributeToElement( {
model: 'bold',
view: ( modelAttributeValue, conversionApi ) => {
const { writer } = conversionApi;
return writer.createAttributeElement( 'span', {
style: 'font-weight:' + modelAttributeValue
} );
}
} );
视图回调的第二个参数是DowncastConversionApi对象。它包含许多在编写更复杂的转换器时可能会有用的属性和方法。
# 更改转换器优先级
如果已经存在其他转换器,你可以优先考虑你的转换器来覆盖现有的转换器。为此,请使用converterPriority
属性
editor.conversion
.for( 'downcast' )
.attributeToElement( {
model: 'bold',
view: 'strong'
} );
editor.conversion
.for( 'downcast' )
.attributeToElement( {
model: 'bold',
view: 'b',
converterPriority: 'high'
} );
在上面的示例中,第一个转换器没有显式设置优先级,因此它假设默认优先级,即normal
。第二个转换器通过将优先级设置为high
来覆盖它。同时使用这两个转换器将导致bold
属性被转换为<b>
元素。
# 属性到属性转换助手
attributeToAttribute()
助手允许注册处理特定属性并将其转换为视图元素属性的转换器。
通常,在为元素注册转换器时(例如,使用elementToElement()
或elementToStructure()
),你将希望在处理元素本身时处理它们的属性。
attributeToAttribute()
助手在出于某种原因你无法在elementToElement()
助手内部覆盖特定属性时非常有用。例如,当你在扩展其他人的插件时。
这种类型的转换器助手仅在已经提供元素转换器的情况下才有效。尝试在没有接收视图元素的情况下转换为属性将导致错误。
# 基本属性到属性转换
此转换导致向视图节点添加属性,基于模型节点的属性。例如,<imageInline src='foo.jpg'></imageInline>
被转换为<img src='foo.jpg'></img>
。
editor.conversion
.for( 'downcast' )
.attributeToAttribute( {
model: 'source',
view: 'src'
} );
# 转换特定的模型元素和属性
上面的转换器将转换文档中的所有source
模型属性。你可以通过提供模型元素名称来限制它的范围。你可以通过以下代码实现
editor.conversion
.for( 'downcast' )
.attributeToAttribute( {
model: {
name: 'imageInline',
key: 'source'
},
view: 'src'
} );
此更新后的转换器将只转换imageInline
模型元素上存在的source
模型属性。
# 从选定的模型值列表创建自定义视图元素
一旦你在model.values
属性中提供数组,view
属性就应该是一个对象,其键与这些值匹配。使用下面的示例可以更好地解释这一点
editor.conversion
.for( 'downcast' )
.attributeToAttribute( {
model: {
name: 'styled',
values: [ 'dark', 'light' ]
},
view: {
dark: {
key: 'class',
value: [ 'styled', 'styled-dark' ]
},
light: {
key: 'class',
value: [ 'styled', 'styled-light' ]
}
}
} );
# 根据模型值创建具有自定义值的视图属性
视图属性的值可以在转换器中修改。以下是一个简单的映射器,它根据模型属性值设置类属性
editor.conversion
.for( 'downcast' )
.attributeToAttribute( {
model: 'styled',
view: modelAttributeValue => ( {
key: 'class',
value: 'styled-' + modelAttributeValue
} )
} );
值得注意的是,以这种方式提供样式属性需要返回的 value
为一个对象
editor.conversion
.for( 'downcast' )
.attributeToAttribute( {
model: 'lineHeight',
view: modelAttributeValue => ( {
key: 'style',
value: {
'line-height': modelAttributeValue,
'border-bottom': '1px dotted #ba2'
}
} )
} );
# 更改转换器优先级
您可以通过指定更高的优先级来覆盖现有的转换器,例如以下示例
editor.conversion
.for( 'downcast' )
.attributeToAttribute( {
model: 'source',
view: 'href'
} );
editor.conversion
.for( 'downcast' )
.attributeToAttribute( {
model: 'source',
view: 'src',
converterPriority: 'high'
} );
第一个转换器具有默认优先级 normal
。第二个转换器将被更早调用,因为它具有更高的优先级,因此 source
模型属性将被转换为 src
视图属性而不是 href
。
# 进一步阅读
我们每天都在努力使我们的文档保持完整。您是否发现过时信息?是否有内容缺失?请通过我们的 问题跟踪器 报告。
随着 42.0.0 版本的发布,我们重新编写了大部分文档以反映新的导入路径和功能。感谢您的反馈,帮助我们确保其准确性和完整性。