【问题标题】:Editing an entity's decorated text编辑实体的修饰文本
【发布时间】:2017-05-11 14:37:19
【问题描述】:

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

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

我们如何查找和替换文本?有没有办法解决这个问题?

(我尝试将 Draft 中的内容设置为任意单个字符并让装饰器显示内容/标题(这很好),但是当尝试删除图形时,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 传入的修饰文本。

【问题讨论】:

  • 点击提示用户设置新的链接文本或链接href?
  • @JiangYD 这就是我对模态所做的。但是从装饰者那里,我怎么能更新草稿中的内容呢?
  • 我不明白你需要做什么。 content 是什么意思?编辑状态下的一切都是内容。也许一些代码或图片使问题更清楚。
  • 我不知道你是怎么设置文本的,所以不能帮助更多。但是https://draftjs.org/docs/api-reference-modifier.html#replacetext 应该可以工作
  • @JiangYD 是的,这是我的问题。我无法在装饰器中访问contentState ????

标签: draftjs


【解决方案1】:

所以我终于在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');

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

【讨论】:

    【解决方案2】:

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

    const compositeDecorator = new CompositeDecorator([
    {
        strategy: handleStrategy,
        component: HandleSpan,
        props: {parent:refToYourComponentWhichContainsTheEditorState}
    }
    
    props.parent.state.editorState.getCurrentContent()
    

    【讨论】:

      猜你喜欢
      • 2012-03-07
      • 1970-01-01
      • 1970-01-01
      • 2017-07-21
      • 2014-09-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多