【问题标题】:How to insert / upload image (update entity and blocks) in Draft.js?如何在 Draft.js 中插入/上传图像(更新实体和块)?
【发布时间】:2017-12-02 03:57:52
【问题描述】:

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

根据我的理解,我需要mergeData 更新实体和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);

【问题讨论】:

  • 你在合并blockData 为什么块的大小会增加?
  • @NanduKalidindi 假设mergeBlockData 既不是替换也不是添加,它的作用是什么?我应该使用哪个正确的 API?
  • 我正在做一个 sn-p。但我想如果你想添加新块,你应该使用ContentBlock
  • @NanduKalidindi 你介意添加一个演示如何使用ContentBlock 在答案中添加新块吗?谢谢

标签: javascript reactjs draftjs


【解决方案1】:

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

  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 image plugin

现场演示:codesandbox

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


如果你想从本地文件中插入图片,你可以尝试使用FileReader API 来获取那个base64。

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

现场演示:jsbin

现在把它们放在一起,你可以从本地文件上传图片!

【讨论】:

  • 原子块不可擦除
  • 感谢@Hongbo,顺便说一下 createEntity 中的字符串 'image' 区分大小写。您需要使用 IMAGE 否则它将无法正常工作。
【解决方案2】:

如果你使用draft-js image plugin,你可以通过如下方式实现。

按照@Hongbo Miao 的说明获取图片的base64。

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

【讨论】:

    【解决方案3】:

    如果你想插入一个新块,那么你可能想使用ContentBlock 而不是mergeBlockData

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

    请试试这个 sn-p。

    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));
    }
    

    【讨论】:

    • 非常感谢,我在检查源代码后才找到解决方案,我将发布另一个答案,包括更新实体和块以尽快插入图像。
    • genKey() 方法在哪里定义?
    • @DimitriosDesyllas 这是从DraftJS 库导入的方法。请检查更新后的 sn-p。
    猜你喜欢
    • 1970-01-01
    • 2017-12-23
    • 1970-01-01
    • 1970-01-01
    • 2023-03-20
    • 1970-01-01
    • 1970-01-01
    • 2019-12-07
    • 1970-01-01
    相关资源
    最近更新 更多