DraftJs创建最简单的自定义块

时间:2017-03-10 13:04:33

标签: javascript reactjs draftjs

在草稿中实现自定义块的最简单方法是什么? 目前我正在将此功能用于默认块

  editorToggleBlockType = (blockType) => {
    this.onChange(
      RichUtils.toggleBlockType(
        this.state.editorState,
        blockType
      )
    );
  }

然后我可以使用blockStyler

应用自定义类
  blockStyler = (block) => {
    if (block.getType() === 'unstyled') {
     return 'paragraph';
    } else {
     return `custom-${block.getType()}`;
    }
  }

可悲的是,blockType只接受blockquote,ol,code-block等默认类型,并且在自定义类型上给我一个错误。

Uncaught TypeError: Cannot read property 'wrapper' of undefined

我的问题是 - 如何强制编辑器接受自定义块类型,以便我可以将className应用于它们?谢谢。

1 个答案:

答案 0 :(得分:2)

您需要在blockRenderMap中定义它。

来自docs

const blockRenderMap = Immutable.Map({
  'atomic': {
    // the docs use 'MyCustomBlock', but I changed it to 'atomic' to make it easier to follow.
    // element is used during paste or html conversion to auto match your component;
    // it is also retained as part of this.props.children and not stripped out
    element: 'section',
    wrapper: <MyCustomBlock {...this.props} />
  }
});


// Include 'paragraph' as a valid block and updated the unstyled element but
// keep support for other draft default block types
const extendedBlockRenderMap = Draft.DefaultDraftBlockRenderMap.merge(blockRenderMap);

class RichEditor extends React.Component {
  render() {
    return (
      <Editor
        ...
        blockRenderMap={extendedBlockRenderMap}
      />
    );
  }
}

相当令人困惑的是,所有这一切都是将自定义块包装在wrapper键中指定的任何内容中。然后由blockRendererFn呈现实际块,如docs

function myBlockRenderer(contentBlock) {
  const type = contentBlock.getType();
  if (type === 'atomic') {
    return {
      component: MediaComponent,
      editable: false,
      props: {
        foo: 'bar',
      },
    };
  }
}

// Then...
import {Editor} from 'draft-js';
class EditorWithMedia extends React.Component {
  ...
  render() {
    return <Editor ... blockRendererFn={myBlockRenderer} />;
  }
}

如果我们逐字地遵循此示例,您将获得一个类似于以下内容的块:

...
<MyCustomBlock>
  <MediaComponent />
</MyCustomBlock>
...

来自className的{​​{1}}会传递给blockStyleFn,因此您可以将其传递给您喜欢的任何原生DOM节点。这也是您获取MyCustomBlock的原因 - DraftJS无法在TypeError中找到您的自定义块!

我希望这能回答你的问题。 DraftJS可能令人困惑,但它是构建RTE的一个非常强大的框架。