Draft.js-添加未选择文本的链接

Nic*_*ick 4 draftjs

如何添加链接?我知道如何将链接添加到选择

          const contentState = editorState.getCurrentContent();
          const contentStateWithEntity = contentState.createEntity(
            'LINK',
            'MUTABLE',
            {url: urlValue}
          );
          const entityKey = contentStateWithEntity.getLastCreatedEntityKey();
          const newEditorState = EditorState.set(editorState, { currentContent: contentStateWithEntity });
          this.setState({
            editorState: RichUtils.toggleLink(
              newEditorState,
              newEditorState.getSelection(),
              entityKey
            )}
Run Code Online (Sandbox Code Playgroud)

我们得到选择newEditorState.getSelection()并添加链接。

但是如何添加链接而不选择呢?a如果未选择文本,仅添加带有文本的新标签?如果我不选择任何文本,则不会添加任何内容。

Pav*_*nyi 7

我非常简洁的解决方案。带有很酷的注释

insertLink = (type, data, text) => {
    const editorState = this.state.editorState;
    const contentState = editorState.getCurrentContent();
    const selection = editorState.getSelection();
    const textWithSpace = text.concat(' ');
    // create new content with text
    const newContent = Modifier.insertText(
      contentState,
      selection,
      textWithSpace,
    );
    // create new link entity
    const newContentWithEntity = newContent.createEntity(
      type,
      'MUTABLE',
      data,
      false,
    );
    const entityKey = newContentWithEntity.getLastCreatedEntityKey();
    // create new selection with the inserted text
    const anchorOffset = selection.getAnchorOffset();
    const newSelection = new SelectionState({
      anchorKey: selection.getAnchorKey(),
      anchorOffset,
      focusKey: selection.getAnchorKey(),
      focusOffset: anchorOffset + text.length,
    });
    // and aply link entity to the inserted text
    const newContentWithLink = Modifier.applyEntity(
      newContentWithEntity,
      newSelection,
      entityKey,
    );
    // create new state with link text
    const withLinkText = EditorState.push(
      editorState,
      newContentWithLink,
      'insert-characters',
    );
    // now lets add cursor right after the inserted link
    const withProperCursor = EditorState.forceSelection(
      withLinkText,
      newContent.getSelectionAfter(),
    );
    // update the editor with all changes
    this.setState({editorState: withProperCursor });
  };
Run Code Online (Sandbox Code Playgroud)


Mik*_*kov 5

您可以使用编辑器状态执行任何操作,而无需更新组件。因此,您可以添加所需的文本,然后以编程方式对此文本进行选择,最后创建一个链接并更新您的组件。

看一下这个工作示例-https://jsfiddle.net/levsha/2op5cyxm/ 在这里,单击按钮后,我添加了一个链接。

handleAddLink = () => {
  const { editorState } = this.state;
  const selectionState = editorState.getSelection();
  const contentState = editorState.getCurrentContent();
  const currentBlock = contentState.getBlockForKey(selectionState.getStartKey());
  const currentBlockKey = currentBlock.getKey();
  const blockMap = contentState.getBlockMap();
  const blocksBefore = blockMap.toSeq().takeUntil((v) => (v === currentBlock));
  const blocksAfter = blockMap.toSeq().skipUntil((v) => (v === currentBlock)).rest();
  const newBlockKey = genKey();

  // add new ContentBlock to editor state with appropriate text

  const newBlock = new ContentBlock({
    key: newBlockKey,
    type: 'unstyled',
    text: linkText,
    characterList: new List(Repeat(CharacterMetadata.create(), linkText.length)),
  });

  const newBlockMap = blocksBefore.concat(
    [[currentBlockKey, currentBlock], [newBlockKey, newBlock]],
    blocksAfter
  ).toOrderedMap();

  const selection = editorState.getSelection();

  const newContent = contentState.merge({
    blockMap: newBlockMap,
    selectionBefore: selection,
    selectionAfter: selection.merge({
      anchorKey: newBlockKey,
      anchorOffset: 0,
      focusKey: newBlockKey,
      focusOffset: 0,
      isBackward: false,
    }),
  });

  let newEditorState = EditorState.push(editorState, newContent, 'split-block');

  // programmatically apply selection on this text 

  const newSelection = new SelectionState({
    anchorKey: newBlockKey,
    anchorOffset: 0,
    focusKey: newBlockKey,
    focusOffset: linkText.length
  });

  newEditorState = EditorState.forceSelection(newEditorState, newSelection);

  // create link entity

  const newContentState = newEditorState.getCurrentContent();

  const contentStateWithEntity = newContentState.createEntity(
    'LINK',
    'IMMUTABLE',
    { url: linkUrl }
  );

  const entityKey = contentStateWithEntity.getLastCreatedEntityKey();
  newEditorState = EditorState.set(newEditorState, { currentContent: contentStateWithEntity });

  newEditorState = RichUtils.toggleLink(newEditorState, newEditorState.getSelection(), entityKey);

  // reset selection

  newSelection = new SelectionState({
    anchorKey: newBlockKey,
    anchorOffset: linkText.length,
    focusKey: newBlockKey,
    focusOffset: linkText.length
  });

  newEditorState = EditorState.forceSelection(newEditorState, newSelection);

  // update our component

  this._handleChange(newEditorState);
}
Run Code Online (Sandbox Code Playgroud)