在 DraftJS 中设置自定义类型
Set Custom Defined Type in DraftJS
我很好奇我们是否可以定义自己的块类型而不是使用来自 DRAFTBLOCKTYPE 的块类型。
目前我正在玩draft-wysiwyg which uses plugin named draft-image-plugin。问题是我必须传递 block-image
作为块的类型而不是 atomic
来使插件工作。
实际上,我曾尝试使用 this 中的解决方案,我将插件的类型重写为 atomic
。但它会影响应用程序上其他类型为 atomic
的块,我无法在其中创建自己的 blockRendererFn,因为 blockRenderer 是该插件的 blockRenderer 'swallowed'。
要将块类型设置为atomic
,我可以通过以下方式轻松实现:
AtomicBlockUtils.insertAtomicBlock(
editorState,
entityKey,
' '
)
如何将块类型设置为任何自定义类型,例如 block-image
或 block-table
?这可能吗?
是的,这是可能的,而且您有几个不同的选择。以下是我知道的一些:
如果您可以控制呈现 atomic
类型块的组件,那么将您的新类型作为实体添加到这些块可能是最简单的。
如果这不是一个选项,它会变得有点麻烦。 AtomicBlockUtils
实际上只是一个模块,旨在帮助人们更轻松地创建媒体(原子)块(尽管将来可能会添加更多实用功能)。如果你想要完全相同的行为,但使用不同的类型,你可以复制 that module 并将 'atomic'
与其他东西交换(例如 'block-image'
或一个变量以使其更多 generic/resuable).
他们使用的技术基本上是创建一个空块的选择,然后使用 Modifier.setBlockType() 函数给它一个新的块类型:
const asAtomicBlock = DraftModifier.setBlockType(
afterSplit, // ContentState
insertionTarget, // SelectionState
'atomic' // your custom type
);
- 在 this example 中,作者创建了自己的版本,称为
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
})}
/>
我很好奇我们是否可以定义自己的块类型而不是使用来自 DRAFTBLOCKTYPE 的块类型。
目前我正在玩draft-wysiwyg which uses plugin named draft-image-plugin。问题是我必须传递 block-image
作为块的类型而不是 atomic
来使插件工作。
实际上,我曾尝试使用 this 中的解决方案,我将插件的类型重写为 atomic
。但它会影响应用程序上其他类型为 atomic
的块,我无法在其中创建自己的 blockRendererFn,因为 blockRenderer 是该插件的 blockRenderer 'swallowed'。
要将块类型设置为atomic
,我可以通过以下方式轻松实现:
AtomicBlockUtils.insertAtomicBlock(
editorState,
entityKey,
' '
)
如何将块类型设置为任何自定义类型,例如 block-image
或 block-table
?这可能吗?
是的,这是可能的,而且您有几个不同的选择。以下是我知道的一些:
如果您可以控制呈现
atomic
类型块的组件,那么将您的新类型作为实体添加到这些块可能是最简单的。如果这不是一个选项,它会变得有点麻烦。
AtomicBlockUtils
实际上只是一个模块,旨在帮助人们更轻松地创建媒体(原子)块(尽管将来可能会添加更多实用功能)。如果你想要完全相同的行为,但使用不同的类型,你可以复制 that module 并将'atomic'
与其他东西交换(例如'block-image'
或一个变量以使其更多 generic/resuable).他们使用的技术基本上是创建一个空块的选择,然后使用 Modifier.setBlockType() 函数给它一个新的块类型:
const asAtomicBlock = DraftModifier.setBlockType(
afterSplit, // ContentState
insertionTarget, // SelectionState
'atomic' // your custom type
);
- 在 this example 中,作者创建了自己的版本,称为
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
})}
/>