使用 draft.js,您如何添加带有元数据的自定义链接实体?我所做的示例:对于我的编辑器菜单按钮之一,我添加了一个单击处理程序,该处理程序创建了一个名为“META_WRAPPER”的实体:
const handleMetaWrapperBtnClick = () => {
const elementType = link ? 'MW_LINK' : 'MW_SPAN'
const newEditorState = applyEntityWithData(editorState, 'META_WRAPPER', {
elementType,
id,
url: link,
text: text,
})
if (newEditorState) {
setEditorState(newEditorState)
}
closeDialog()
}
我添加了一个装饰器策略和组件来处理由上述 handleMetaWrapperBtnClick 添加的自定义“META_WRAPPER”实体:
找到'META_WRAPPER'的策略-
export const metaWrapperStrategy = (
contentBlock: ContentBlock,
callback: (a: any, b: any) => any,
contentState: ContentState
) => {
contentBlock.findEntityRanges((character) => {
const entityKey = character.getEntity()
return entityKey !== null && contentState.getEntity(entityKey).getType() === 'META_WRAPPER'
}, callback)
}
为 metaWrapperStrategy 找到的自定义 META_WRAPPER 渲染的装饰器组件:
export const MetaWrapper: React.FC = (props: any) => {
const { elementType } = props.contentState.getEntity(props.entityKey).getData()
switch (elementType) {
case 'MW_LINK':
return <MwLink {...props} />
default:
//MW_SPAN
return <MwSpan {...props} />
}
}
const MwLink: React.FC = (props: any) => {
const classes = useStyles()
const { id, url, text } = props.contentState.getEntity(props.entityKey).getData()
return (
<a rel="nofollow noreferrer" id={id} href={url} className={classes.mwLink}>
{text || props.children}
</a>
)
}
const MwSpan: React.FC = (props: any) => {
const classes = useStyles()
const { id, text } = props.contentState.getEntity(props.entityKey).getData()
return (
<span id={id} className={classes.mwSpan}>
{text || props.children}
</span>
)
}
const customDecorators = [
{
strategy: metaWrapperStrategy,
component: MetaWrapper,
},
]
const compositeDecorator = new CompositeDecorator(customDecorators)
奇怪的是,上面的内容仅在本地工作,并且仅在我放置断点并逐步执行代码时才有效:
- 调用 handleMetaWrapperBtnClick 处理程序,这将导致使用新的自定义实体更新编辑器状态,
- MetaWrapperStrategy 运行
- MetaWrapper 组件作为结果呈现
- 成功 - 选择被编辑器内的自定义 MwSpan 或 MwLink 替换。(MwSpan 或 MwLink 之一将根据 elementType 元字段的值呈现)
但是,在没有断点的情况下运行代码时,编辑器中的选择不会发生任何变化。
此外,当它工作时,不可能将粗体文本等内联样式添加到同一选择中。
我还创建了这个 CodeSanbox 来演示这个问题:https ://codesandbox.io/s/dry-river-qlysv?file=/src/Components/DraftEditor.js