编辑实体的装饰文本
Editing an entity's decorated text
我们有一个 Figure
装饰器,它允许我们插入一个 link,您可以将鼠标悬停在上面以预览图像。我们使用模态形式将此图像与一些元数据(标题等)一起插入。这一切都很好。但是,我们还希望能够单击 link 并弹出模式以对其进行编辑。
Entity.replaceData()
非常适合更新元数据,唯一剩下的问题是来自模态的装饰文本。实体似乎对其装饰的内容知之甚少。
我们如何查找和替换文本?有解决办法吗?
(我试过将 Draft 中的内容设置为任意单个字符,并让装饰器显示 content/title(这没问题),但是当尝试删除图形时,Draft 似乎跳了覆盖内容并删除它之前的内容。我猜这是由于不同的文本长度。我认为将其设置为 'IMMUTABLE' 会解决这个问题,但没有帮助。)
编辑:
这是我的装饰器:
function LinkedImageDecorator(props: Props) {
Entity.mergeData(props.entityKey, { caption: "hello world" });
const entity = Entity.get(props.entityKey);
const data = entity.getData();
return <LinkedImage data={data} text={props.children} offsetKey={props.offsetKey} />
}
function findLinkedImageEntities(contentBlock: ContentBlock, callback: EntityRangeCallback) {
contentBlock.findEntityRanges((character) => {
const entityKey = character.getEntity();
return (
entityKey != null &&
Entity.get(entityKey).getType() === ENTITY_TYPE.IMAGE
);
}, callback);
}
export default {
strategy: findLinkedImageEntities,
component: LinkedImageDecorator,
editable: false,
};
如您所见,我正在测试 Entity.mergeData
,它最终将成为我的 LinkedImage
组件的回调(它将打开模态 onClick。)因此元数据很容易更新,我只需要能够更新作为 props.children
.
传入的装饰文本
只需将全局组件实例引用放在装饰器道具中即可。
const compositeDecorator = new CompositeDecorator([
{
strategy: handleStrategy,
component: HandleSpan,
props: {parent:refToYourComponentWhichContainsTheEditorState}
}
props.parent.state.editorState.getCurrentContent()
所以我终于在Jiang YD and tobiasandersen的帮助下解决了这个问题。开始了...
首先,我在装饰器中注入对我的编辑器的引用(它跟踪 EditorState
):
const decorators = new CompositeDecorator([{
strategy: findLinkedImageEntities,
component: LinkedImageDecorator,
props: { editor: this }
}];
this.editorState = EditorState.set(this.editorState, { decorator });
从那里我可以在我的 LinkedImageDecorator
:
中执行此操作
const { decoratedText, children, offsetKey, entityKey, editor } = this.props;
// This looks messy but seems to work fine
const { startOffset, blockKey } = children['0'].props;
const selectionState = SelectionState.createEmpty(blockKey).merge({
anchorOffset: startOffset,
focusOffset: startOffset + decoratedText.length,
});
const editorState = editor.getEditorState();
let newState = Modifier.replaceText(
editorState.getCurrentContent(),
selectionState,
"my new text",
null,
entityKey,
);
editor.editorState = EditorState.push(editorState, newState, 'insert-fragment');
不确定这是否是最简洁的方法,但它似乎运行良好!
我们有一个 Figure
装饰器,它允许我们插入一个 link,您可以将鼠标悬停在上面以预览图像。我们使用模态形式将此图像与一些元数据(标题等)一起插入。这一切都很好。但是,我们还希望能够单击 link 并弹出模式以对其进行编辑。
Entity.replaceData()
非常适合更新元数据,唯一剩下的问题是来自模态的装饰文本。实体似乎对其装饰的内容知之甚少。
我们如何查找和替换文本?有解决办法吗?
(我试过将 Draft 中的内容设置为任意单个字符,并让装饰器显示 content/title(这没问题),但是当尝试删除图形时,Draft 似乎跳了覆盖内容并删除它之前的内容。我猜这是由于不同的文本长度。我认为将其设置为 'IMMUTABLE' 会解决这个问题,但没有帮助。)
编辑:
这是我的装饰器:
function LinkedImageDecorator(props: Props) {
Entity.mergeData(props.entityKey, { caption: "hello world" });
const entity = Entity.get(props.entityKey);
const data = entity.getData();
return <LinkedImage data={data} text={props.children} offsetKey={props.offsetKey} />
}
function findLinkedImageEntities(contentBlock: ContentBlock, callback: EntityRangeCallback) {
contentBlock.findEntityRanges((character) => {
const entityKey = character.getEntity();
return (
entityKey != null &&
Entity.get(entityKey).getType() === ENTITY_TYPE.IMAGE
);
}, callback);
}
export default {
strategy: findLinkedImageEntities,
component: LinkedImageDecorator,
editable: false,
};
如您所见,我正在测试 Entity.mergeData
,它最终将成为我的 LinkedImage
组件的回调(它将打开模态 onClick。)因此元数据很容易更新,我只需要能够更新作为 props.children
.
只需将全局组件实例引用放在装饰器道具中即可。
const compositeDecorator = new CompositeDecorator([
{
strategy: handleStrategy,
component: HandleSpan,
props: {parent:refToYourComponentWhichContainsTheEditorState}
}
props.parent.state.editorState.getCurrentContent()
所以我终于在Jiang YD and tobiasandersen的帮助下解决了这个问题。开始了...
首先,我在装饰器中注入对我的编辑器的引用(它跟踪 EditorState
):
const decorators = new CompositeDecorator([{
strategy: findLinkedImageEntities,
component: LinkedImageDecorator,
props: { editor: this }
}];
this.editorState = EditorState.set(this.editorState, { decorator });
从那里我可以在我的 LinkedImageDecorator
:
const { decoratedText, children, offsetKey, entityKey, editor } = this.props;
// This looks messy but seems to work fine
const { startOffset, blockKey } = children['0'].props;
const selectionState = SelectionState.createEmpty(blockKey).merge({
anchorOffset: startOffset,
focusOffset: startOffset + decoratedText.length,
});
const editorState = editor.getEditorState();
let newState = Modifier.replaceText(
editorState.getCurrentContent(),
selectionState,
"my new text",
null,
entityKey,
);
editor.editorState = EditorState.push(editorState, newState, 'insert-fragment');
不确定这是否是最简洁的方法,但它似乎运行良好!