如何在 Draft.js 中插入/上传图像(更新实体和块)?

IT技术 javascript reactjs draftjs
2021-03-27 03:26:34

我正在尝试将图像插入 Draft.js 编辑器。

根据我的理解,我需要 update entity bymergeData和 blocks by mergeBlockData(我不确定)

现在我正在尝试使用mergeBlockData插入块。

mergeBlockData(
  contentState: ContentState,
  selectionState: SelectionState,
  blockData: Map<any, any>
): ContentState

请阅读代码中的注释。

import { Map } from 'immutable';

const selection = this.state.editorState.getSelection();
const contentState = this.state.editorState.getCurrentContent();

console.log(convertToRaw(contentState));  // for example, I have 3 blocks

const blockData = Map({ ov72: {  // here how to generate a random valid key?
  "key": "ov72",
  "text": " ",
  "type": "atomic",
  "depth": 0,
  "inlineStyleRanges": [],
  "entityRanges": [{
    "offset": 0,
    "length": 1,
    "key": 1
  }],
  "data": {}
}});
const newContentState = Modifier.mergeBlockData(contentState, selection, blockData);

console.log(convertToRaw(newContentState));  // here is wrong, still 3 blocks. Also original blocks have no change

const newEditorState = EditorState.push(this.state.editorState, newContentState);
3个回答

花了一段时间才弄清楚如何插入图像。

  insertImage = (editorState, base64) => {
    const contentState = editorState.getCurrentContent();
    const contentStateWithEntity = contentState.createEntity(
      'image',
      'IMMUTABLE',
      { src: base64 },
    );
    const entityKey = contentStateWithEntity.getLastCreatedEntityKey();
    const newEditorState = EditorState.set(
      editorState,
      { currentContent: contentStateWithEntity },
    );
    return AtomicBlockUtils.insertAtomicBlock(newEditorState, entityKey, ' ');
  };

然后你可以使用

const base64 = 'aValidBase64String';
const newEditorState = this.insertImage(this.state.editorState, base64);
this.setState({ editorState: newEditorState });

对于渲染图像,您可以使用Draft.js 图像插件

现场演示: codesandbox

该演示插入了 Twitter 徽标图像。


如果要从本地文件插入图像,可以尝试使用FileReaderAPI 获取该 base64。

关于如何获取base64,很简单,查看

现场演示: jsbin

现在继续将它们放在一起,您可以从本地文件上传图像!

原子块不可擦除
2021-06-02 03:26:34
谢谢@Hongbo,顺便说一下,createEntity 中的字符串 'image' 区分大小写。你需要使用 IMAGE 否则它不会工作。
2021-06-11 03:26:34

如果您使用Draft-js 图像插件,您可以按如下方式实现。

按照@Hongbo Miao 的解释获取图像的 base64。

const imagePlugin = createImagePlugin();//initialize image plugin
const base64 = 'aValidBase64String';
const newEditorState = imagePlugin.addImage(this.state.editorState, base64);
this.setState({ editorState: newEditorState });

如果你想插入一个新的 Block 那么你可能想要使用ContentBlock而不是mergeBlockData.

内容块https : //draftjs.org/docs/api-reference-content-block.html#content

请试试这个片段。

import { genKey } from 'draft-js'

addNewBlock(editorState) {
  const text = 'Alpha';
  const block = new ContentBlock({
    key: genKey(),
    type: 'unstyled',
    text,
  });

  const contentState = editorState.getCurrentContent();
  const blockMap = contentState.getBlockMap().set(block.key, block);                   

  return EditorState.push(editorState, contentState.set('blockMap', blockMap));
}
@DimitriosDesyllas 这是从DraftJS库中导入的方法请检查更新的代码段。
2021-05-24 03:26:34
genKey()方法在哪里定义
2021-05-29 03:26:34
真的很感激,我在检查源代码后才找到解决方案,我将发布另一个答案,包括更新实体和块以尽快插入图像。
2021-06-05 03:26:34