0

我有一个 Draft.js 编辑器,里面有一些 HTML。如何在当前选择位置插入一段新的 HTML,同时保留样式和实体/块映射?我知道如何通过以下方式插入原始文本Modifier.insertText

const contentState = Modifier.insertText(
  editorState.getCurrentContent(),
  editorState.getSelection(),
  insertionText,
  editorState.getCurrentInlineStyle(),
);

但它会剥离所有不好的 HTML。

// Original HTML piece
const { contentBlocks, entityMap } = htmlToDraft(originalHTML);
const contentState = ContentState.createFromBlockArray(
  contentBlocks,
  entityMap,
);
const editorState = EditorState.createWithContent(contentState);

// Additional HTML piece, which I want to insert at the selection (cursor) position of
// previous editor state
const { contentBlocks, entityMap } = htmlToDraft(newHTML);
const newContentState = ContentState.createFromBlockArray(
  contentBlocks,
  entityMap,
);

4

2 回答 2

0

我无法将其发布在评论部分(片段太长),但正如前面提到Modifier.replaceWithFragment的那样,这是要走的路,所以我让它像下面的片段一样工作。

*** 确保您拥有所有其他基础设施,例如blockRendererFn, blockRenderMap,compositeDecorator等来实际渲染所有这些块、链接的内联样式、图像等

import {
    Modifier,
    ContentState,
    convertFromHTML,
} from 'draft-js'

onPaste = (text, html, state) => {
    if (html) {
        const blocks = convertFromHTML(html)
        Modifier.replaceWithFragment(
            this.state.editorState.getCurrentContent(),
            this.state.editorState.getSelection(),
            ContentState.createFromBlockArray(blocks, blocks.entityMap).getBlockMap(),
        )
    }
    return false
}
于 2020-12-26T23:57:17.147 回答
0

您可能应该Modifier.replaceWithFragment为此使用:

“片段”是块映射的一部分,实际上只是一个 OrderedMap,与 ContentState 对象的完整块映射非常相似。此方法将用片段替换“目标”范围。

这将与 相同insertText,除了您需要为其提供块图作为参数。从您的示例中并不完全清楚返回值htmlToDraft是什么,但您应该可以:

  • contentBlocks直接从返回值使用
  • 或者在您的示例中创建一个contentState,然后使用它的.getBlockMap()方法获取块映射以插入到编辑器的内容中。
const newContentState = ContentState.createFromBlockArray(
  contentBlocks,
  entityMap,
);
// Use newContentState.getBlockMap()
于 2019-09-26T20:49:32.107 回答