如何在Facebook Draft.js中创建带有装饰器的Link实体

时间:2017-04-24 12:31:54

标签: javascript facebook reactjs draftjs

我正在使用Facebook Draft.js,我需要在文本中检测到有效网址时创建LINK实体。

目前,我正在使用一个装饰器来实现一个策略,检测文本中是否存在链接,例如draft-js-linkify-plugin,但是我有一些麻烦将文本修改为一个不可变的LINK实体。

事实上,我使用编辑道具装饰,但我无法修改编辑器的状态,因此,应用这个新的LINK实体。

装饰者:

const decorator = new CompositeDecorator([{
    strategy: findLinks,
    component: decorateComponentWithProps(Link, {
        getEditorState: this.getEditorState.bind(this),
        setEditorState: this.onChange.bind(this)
    }),
}]);

策略:

function findLinks(contentBlock, callback) {
    const links = linkify.match(contentBlock.getText());
    if (links) {
        links.map(link => callback(link.index, link.lastIndex))
    }
}

组件:

const Link = (props) => {
    const editorState = props.getEditorState();
    const contentState = editorState.getCurrentContent();
    const selectionState = editorState.getSelection();

    const contentStateWithEntity = contentState.createEntity(
        'LINK',
        'IMMUTABLE',
        { url: props.decoratedText }
    );
    const entityKey = contentStateWithEntity.getLastCreatedEntityKey();

    const contentStateWithLink = Modifier.applyEntity(
        contentStateWithEntity,
        selectionState,
        entityKey
    );

    const entity = contentStateWithLink.getEntity(entityKey);
    const { url } = entity.getData();
    const type = entity.getType();

    const newEditorState = EditorState.set(editorState, {
        currentContent: contentStateWithEntity
    });
    props.setEditorState(newEditorState);

    return <a href={url} target="_blank">{url}</a>;
};

我知道slectionState中存在问题或检索文本块并修改它而不是创建新实体,但我有点丢失。我甚至使用正确的逻辑来制作它吗?

感谢您的帮助,

1 个答案:

答案 0 :(得分:0)

我没有看到在React Draft中使用装饰器构建<a>标记的特定问题的解决方案,并且仍然可以编辑它们而不会发生冲突。

但是,这里有两种选择:

  1. 选择文本并单击链接按钮时创建链接实体 正如反应草案示例中所详述的那样。

  2. 使用装饰器在编辑器中显示链接,然后在提交时, 通过检索链接并将其替换为<a>标记来修改您的内容。 在所有情况下,我仍然认为您需要清理内容服务器端以确保安全。利用这一点,可能会缩短您的链接。

  3. 当您创建文章或博客内容时,第一个解决方案更适合。 当您使用消息系统草稿时,第二个更方便。