CKEditor 5如何直接从模型加载/保存数据而非视图?
你的问题核心是混淆了CKEditor不同场景下的转换规则,当前配置只覆盖了编辑态视图和模型的映射,没有对接后端存储的自定义元素格式,修改两处转换规则即可解决:
1. 新增自定义元素的导入(upcast)规则
原来的upcast规则仅能识别编辑用的span结构,需要新增一条规则专门匹配后端返回的<product-info>自定义元素,将其转换为编辑器模型:
conversion.for('upcast').elementToElement({ view: { name: 'product-info', attributes: [ 'product-id' ] }, model: (viewElement, { writer: modelWriter }) => { const id = viewElement.getAttribute('product-id'); return modelWriter.createElement('product-info', { 'product-id': id }); } });
添加后编辑器加载后端返回的<product-info product-id="123"></product-info>时就会正常识别,不会被过滤。
2. 修改导出(dataDowncast)规则输出自定义元素
你之前把编辑态转换和导出转换用了同一套逻辑,导致getData()返回的是编辑用的span结构,需要单独把dataDowncast规则改成输出自定义元素:
// 编辑态转换规则保留,还是输出带样式的span,避免和Angular Elements冲突 conversion.for('editingDowncast').elementToElement({ model: 'product-info', view: (modelItem, { writer: viewWriter }) => { const widgetElement = createProductInfoView(modelItem, viewWriter); return toWidget(widgetElement, viewWriter); } }); // 导出规则改为输出自定义元素,供后端存储 conversion.for('dataDowncast').elementToElement({ model: 'product-info', view: (modelItem, { writer: viewWriter }) => { const id = modelItem.getAttribute('product-id'); return viewWriter.createEmptyElement('product-info', { 'product-id': id }); } });
修改后调用editor.getData()获取到的就是<product-info product-id="xxx"></product-info>格式,可以直接存入后端。
CKEditor的转换管道是按场景拆分的,三个核心通道各司其职:
- upcast:所有外部内容进入编辑器时的转换规则,包括初始化加载、粘贴等场景,匹配不到规则的元素会被过滤
- editingDowncast:模型转编辑区可视内容的规则,对应你编辑时看到的界面
- dataDowncast:模型转导出数据的规则,对应
getData()返回的内容
你之前的配置把三个场景的转换绑定为同一套逻辑,拆分配置后刚好满足「存储用自定义元素、编辑用span」的需求,也不会和Angular的DOM操作产生冲突。
内容的提问来源于stack exchange,提问作者Daniel Saner
相关产品推荐
相关产品推荐

