无法输入到CKEditor5的EditableElement

无法输入到CKEditor5的EditableElement,ckeditor,ckeditor5,Ckeditor,Ckeditor5,在CKEditor5中,我尝试实现自定义元素以将模型转换为视图进行编辑。然后,容器元素(@ckeditor/ckeditor5 engine/src/view/editableelement)中的可编辑元素(@ckeditor/ckeditor5 engine/src/view/containerelement)集中在父容器元素上,无法编辑 例如,如果按照以下方式实施: buildModelConverter().for(editing.modelToView) .fro

在CKEditor5中,我尝试实现自定义元素以将模型转换为视图进行编辑。然后,容器元素(@ckeditor/ckeditor5 engine/src/view/editableelement)中的可编辑元素(@ckeditor/ckeditor5 engine/src/view/containerelement)集中在父容器元素上,无法编辑

例如,如果按照以下方式实施:

buildModelConverter().for(editing.modelToView)
            .fromElement('myElement')
            .toElement(new ContainerElement('div', {}, [new EditableElement('h4')]));
插入“myElement”并按下“abc”键后实际编辑dom的结果。(我希望将“abc”的文本输入h4标签,但…)

接下来,排名列表中的项目有链接、图像、标题和注释。 因此,排名列表项具有以下DOM结构:

<ol><!-- apply toWidget -->
  <li>
    <a href="link[editable]">
      <img src="image[editable]">
      <h3>title[editable]</h3>
      <p>notes[editable]</p>
    </a>
  </li>
  ...
</ol>
总之,我希望使用可编辑视图,而不是破坏已定义的DOM树。
我怎样才能意识到这一点呢?

谢谢您描述您的案例。目前,了解开发人员如何使用编辑器以及您的期望对我们来说意义重大

不幸的是,这看起来是一个非常复杂的特性。它看起来还需要自定义UI(编辑链接url和图像src——除非它们在添加到编辑器后不会更改)。您似乎面临两个问题:

  • 模型和视图之间的位置映射
  • 嵌套的可编辑项
首先,回答您关于
EditableElement
的问题-将它们用于
h3
p
元素似乎是正确的

const item1 = new ModelElement('rankingListItem');
const item2 = new ModelElement('rankingListItem');
const model = new ModelElement('rankingList', {}, [item1, item2]);
// and insert
然而,这种复杂的特性需要定制转换器。转换器生成器(您使用的)专用于在简单情况下使用,如元素到元素的转换或属性到属性的转换

在niceapi的背后,buildconverter是一个函数工厂,它创建一个或多个函数。然后将它们作为回调添加到
ModelConversionDispatcher
(其中
editor.editing.modelToView
是的一个实例)
ModelConversionDispatcher
在转换过程中触发一系列事件,这是一个将模型中的更改转换为视图的过程

正如我提到的,您必须自己编写这些转换函数

由于这是一个太大的问题,无法给出详细和彻底的答案,我将简要介绍您应该感兴趣的内容。不幸的是,还没有关于从头开始创建自定义转换器的指南。这是一个非常广泛的主题

首先,让我解释一下你的大部分问题来自哪里。如您所知,编辑器有三层:模型(数据)、视图(类似DOM的结构)和DOM。模型转换为视图,视图渲染为DOM。另外,当加载数据时,DOM将转换为视图,视图将转换为模型。这就是为什么您需要为您的功能提供模型到视图转换器和视图到模型转换器

这个难题的重要部分是
引擎.conversion.Mapper
。它的作用是将元素和位置从模型映射到视图。正如您可能已经看到的,模型可能与视图完全不同。正确的位置映射是关键。在插入符号位置(在DOM中)键入字母时,该位置将映射到模型,并将字母插入模型中,然后再转换回视图和DOM。如果视图到模型位置的转换错误,您将无法在该位置键入或执行任何操作

Mapper
本身非常简单。它所需要的只是指定哪些视图图元绑定到哪些模型图元。例如,在模型中,您可能有:

<listItem type="bulleted" indent="0">Foo</listItem>
<listItem type="bulleted" indent="1">Bar</listItem>
假定
myElement
绑定。因此,在
中写入的任何内容都将直接进入
myElement
,然后将在
myElement
的开头呈现:

<div>
  <h4></h4>
</div>
视图:

视图:

其中“Foo”和“Bar”也设置了
linkHref
属性

视图:


  • ...
    这样的东西,虽然还远远不够完美,但只要我们在重构之前和编写指南之前,编写起来就应该容易得多

    当然,您还必须提供视图到模型转换器。您可能希望自己编写它们(查看
    ckeditor5 list/src/converters.js
    viewModelConverter()
    ——尽管您的编写会更简单,因为它是平面的,而不是嵌套的列表)。也可以通过转换器生成器生成它们


    也许可以使用上述方法(更简单),但可以使用
    contentEditable
    属性来控制结构
    rankList
    必须使用
    contentEditable=“false”
    转换为
    。例如,也许您可以使用
    toWidget
    来更好地处理选择
    rankNotes
    rankTitle
    必须转换为具有
    contentEditable=“true”
    (可能使用
    toWidgetEditable()
    )的元素。

    感谢您描述您的案例。目前,了解开发人员如何使用编辑器以及您的期望对我们来说意义重大

    不幸的是,这看起来是一个非常复杂的特性。它看起来还需要自定义UI(编辑链接url和图像src——除非它们在添加到编辑器后不会更改)。您似乎面临两个问题:

    • 模型和视图之间的位置映射
    • 嵌套的可编辑项
    首先,回答您关于
    EditableElement
    的问题-将它们用于
    h3
    p
    元素似乎是正确的

    const item1 = new ModelElement('rankingListItem');
    const item2 = new ModelElement('rankingListItem');
    const model = new ModelElement('rankingList', {}, [item1, item2]);
    // and insert
    
    然而,这种复杂的特性需要定制转换器。转换器生成器(您使用的)专用于在简单情况下使用,如元素到元素的转换或属性到属性的转换

    在niceapi的背后,buildconverter是一个函数工厂,它创建一个或多个函数。T
    <listItem type="bulleted" indent="0">Foo</listItem>
    <listItem type="bulleted" indent="1">Bar</listItem>
    
    <ul>
      <li>
        Foo
        <ul>
          <li>Bar</li>
        </ul>
      </li>
    </ul>
    
    buildModelConverter().for(editing.modelToView)
            .fromElement('myElement')
            .toElement(new ContainerElement('div', {}, [new EditableElement('h4')]));
    
    <div>
      <h4></h4>
    </div>
    
    <myElement>x</myElement>
    
    <div>x<h4></h4></div>
    
    <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>
    
    <rankList>
      <rankItem>
        <rankImage linkHref="" />
        <rankTitle>Foo</rankTitle>
        <rankNotes>Bar</rankNotes>
      </rankItem>
      ...
    </rankList>
    
    <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>