0

我已经在这个问题上工作了一段时间,我希望这不是一个错误。

我正在使用 Draft.js 测试一个文本编辑器,我只是希望我的用户向他们的文章添加一个超链接,所以我通过修改编辑器状态的内容来创建一个函数来实现这一点。

const addLlink = (e) => {
    e.preventDefault();
    const contentState = editorState.getCurrentContent();
    const contentStateWithEntity = contentState.createEntity(
        'LINK', 'MUTABLE', {url: 'https://www.amazon.com'} // link for testing only
    );
    const entityKey = contentStateWithEntity.getLastCreatedEntityKey();
    const contentStateWithLink = Modifier.applyEntity(
        contentStateWithEntity,
        editorState.getSelection(),
        entityKey
    );
    // tried with and without styling
    const styledContentStateWithLink = Modifier.applyInlineStyle(
        contentStateWithLink,
        editorState.getSelection(),
        'HYPERLINK'
    );
    const newState = EditorState.set(editorState, {
        currentContent: styledContentStateWithLink
    });

    setEditorState(newState);
    // Also tried: setEditorState(RichUtils.toggleLink(newState, newState.getSelection(), entityKey));
}

当我触发它时,我只使用了一个 Evergreen-ui 按钮:

<Button onMouseDown={addLlink} appearance="minimal">Link</Button>

我使用 Modifier 对象实现的样式有效,但我似乎无法让链接实际工作。应该注意的是,链接插件作为一个包,效果很好,但这仅用于检测输入/粘贴的 URL(不嵌入到文本中)。

对于使用 React 函数式编程的链接,是否有人有一个实际的工作示例,或者我可能做错了什么的建议?

4

2 回答 2

1

事实证明,我需要添加一个装饰器才能检测到实体。我将此代码放在编辑器组件的上方/外部:

const findLinkEntities = (contentBlock, callback, contentState) => {
contentBlock.findEntityRanges(
  (character) => {
    const entityKey = character.getEntity();
    return (
      entityKey !== null &&
      contentState.getEntity(entityKey).getType() === 'LINK'
    );
  },
  callback
);


}
const Link = (props) => {
    const {url} = props.contentState.getEntity(props.entityKey).getData();
    return (
      <a href={url} >
        {props.children}
      </a>
    );
};

const strategyDecorator = new CompositeDecorator([
    {
      strategy: findLinkEntities,
      component: Link,
    },
]);

基本上,当您使用 EditorState 设置新内容时,它会检测链接实体并将它们转换为元素:

const newState = EditorState.set(editorState, {
        currentContent: styledContentStateWithLink,
        decorator: strategyDecorator
    });
于 2020-10-27T04:42:24.453 回答
1

根据官方示例,您需要添加一个装饰器来查找实体并应用 Link 组件

const decorator = new CompositeDecorator([
  {
    strategy: findLinkEntities,
    component: Link,
  },
]);

当你使用 linkify 插件时,你必须将装饰器传递给插件编辑器

import Editor from "draft-js-plugins-editor";
import createLinkifyPlugin from "draft-js-linkify-plugin";
import "draft-js-linkify-plugin/lib/plugin.css";

...
<Editor
  decorators={[decorator]}
  editorState={editorState}
  onChange={setEditorState}
  plugins={[linkifyPlugin]}
/>
...

您可以在此处查看工作示例https://codesandbox.io/s/test-selection-decorator-draft-js-link-0lblg?file=/src/ExtendedEditor.js

于 2020-10-27T04:42:33.660 回答