Draft.js вставляет один contentState в другой
У меня есть редактор 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,
);
2 ответа
Вам, вероятно, следует использовать Modifier.replaceWithFragment
за это:
"Фрагмент" - это часть блочной карты, фактически просто OrderedMap, почти такая же, как полная блочная карта объекта ContentState. Этот метод заменит "целевой" диапазон на фрагмент.
Это будет работать идентично insertText
, за исключением того, что вам нужно передать ему карту блоков в качестве параметра. Из вашего примера не совсем понятно, какое возвращаемое значениеhtmlToDraft
есть, но вы должны иметь возможность:
- Использовать
contentBlocks
прямо из возвращаемого значения - Или создайте
contentState
как в вашем примере, затем используйте его.getBlockMap()
, чтобы получить карту блоков для вставки в содержимое редактора.
const newContentState = ContentState.createFromBlockArray(
contentBlocks,
entityMap,
);
// Use newContentState.getBlockMap()
Я не мог опубликовать это в разделе комментариев (слишком длинный фрагмент), но, как упоминалось ранее
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
}