3

我很好奇我们是否可以定义自己的块类型而不是使用DRAFTBLOCKTYPE中的一个。

目前我正在玩使用名为draft-image-plugin 的插件的draft-wysiwyg。问题是我必须传递块的类型而不是使插件工作。block-imageatomic

实际上,我曾尝试使用此解决方案,插件的类型覆盖为atomic. 但它会影响应用程序上其他atomic类型的块,在这些块中我无法创建自己的 blockRendererFn,因为 blockRenderer 被该插件的 blockRenderer“吞噬”。

要将块类型设置为atomic,我可以通过以下方式轻松实现:

AtomicBlockUtils.insertAtomicBlock(
  editorState,
  entityKey,
  ' '
)

如何将块类型设置为任何自定义类型,例如block-imageor block-table?这甚至可能吗?

4

1 回答 1

4

是的,这是可能的,你有几个不同的选择。以下是我知道的一些:

  1. 如果您可以控制呈现 type 块的组件,atomic则将新类型作为实体添加到这些块中可能是最简单的。

  2. 如果这不是一个选项,它会变得有点麻烦。AtomicBlockUtils实际上只是一个模块,用于帮助人们更轻松地创建媒体(原子)块(即使将来可能会添加更多实用功能)。如果您想要完全相同的行为,但使用不同的类型,您可以复制该模块'atomic'并与其他东西交换(例如'block-image',或一个变量,使其更通用/可重复使用)。

    他们使用的技术基本上是创建一个空块的选择,然后使用Modifier.setBlockType()函数给它一个新的块类型:

const asAtomicBlock = DraftModifier.setBlockType(
    afterSplit, // ContentState
    insertionTarget, // SelectionState
    'atomic' // your custom type
);
  1. 这个例子中,作者创建了他自己的版本,称为addNewBlock()(虽然它的工作方式与其中的不完全一样AtomicBlockUtils):
/*
Adds a new block (currently replaces an empty block) at the current cursor position
of the given `newType`.
*/
const addNewBlock = (editorState, newType = Block.UNSTYLED, initialData = {}) => {
  const selectionState = editorState.getSelection();
  if (!selectionState.isCollapsed()) {
    return editorState;
  }
  const contentState = editorState.getCurrentContent();
  const key = selectionState.getStartKey();
  const blockMap = contentState.getBlockMap();
  const currentBlock = getCurrentBlock(editorState);
  if (!currentBlock) {
    return editorState;
  }
  if (currentBlock.getLength() === 0) {
    if (currentBlock.getType() === newType) {
      return editorState;
    }
    const newBlock = currentBlock.merge({
      type: newType,
      data: getDefaultBlockData(newType, initialData),
    });
    const newContentState = contentState.merge({
      blockMap: blockMap.set(key, newBlock),
      selectionAfter: selectionState,
    });
    return EditorState.push(editorState, newContentState, 'change-block-type');
  }
  return editorState;
};

因此,如果你想创建一个类型为“block-image”的块,带有 src 属性,你可以像这样使用这个函数:

const newEditorState = addNewBlock(this.state.editorState, 'block-image', { src: 'https://...' })    
this.setState({ editorState: newEditorState })

更新: 如果添加新类型,还需要将其添加到编辑器的 blockRenderMap 中:

import { Map } from 'immutable'

<Editor 
  // editor props
  blockRenderMap={Map({
    ['unstyled']: {
      element: 'div'
    },
    ['block-image']: {
      element: 'div' // or whatever element you want as a wrapper
    },
    // all your other block types
  })}
/>
于 2016-09-02T22:55:02.390 回答