编辑实体的装饰文本

时间:2017-05-11 14:37:20

标签: draftjs

我们有一个Figure装饰器,它允许我们插入一个链接,您可以将鼠标悬停在该链接上以获取图像的预览。我们使用模态表单插入此图像以及一些元数据(标题等)。一切都很好。但是,我们还希望能够单击该链接并弹出模式进行编辑。

Entity.replaceData()非常适合更新元数据,唯一剩下的问题是来自模态的装饰文本。实体似乎对它正在装饰的内容知之甚少。

我们如何找到并替换文字?有办法解决这个问题吗?

(我已尝试将草稿中的内容设置为任意单个字符并使装饰器显示内容/标题(这样会很好),但是当试图删除图形时,草稿似乎跳过了内容和在它之前删除一些东西。我想这是由于文本长度的不同。我认为将它设置为“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传递的装饰文本。

2 个答案:

答案 0 :(得分:4)

所以我终于在Jiang YDtobiasandersen的帮助下解决了这个问题。这就是......

首先,我向我的装饰者注入一个对我的编辑器的引用(跟踪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');

不确定这是否是最干净的方法,但它似乎运作良好!

答案 1 :(得分:1)

将全局组件实例引用放在装饰器道具中。

const compositeDecorator = new CompositeDecorator([
{
    strategy: handleStrategy,
    component: HandleSpan,
    props: {parent:refToYourComponentWhichContainsTheEditorState}
}

props.parent.state.editorState.getCurrentContent()