Draft.js 使用 applyEntity 添加超链接似乎不起作用
Draft.js adding hyperlink using applyEntity doesn't seem to work
我已经研究这个问题一段时间了,希望这不是一个错误。
我正在使用 Draft.js 测试一个文本编辑器,我只是希望我的用户在他们的文章中添加一个 hyperlink,所以我创建了一个函数来实现它修改编辑器状态的内容。
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 对象实现的样式有效,但我似乎无法使 link 实际起作用。应该注意的是,link 插件作为一个包,效果很好,但这仅用于检测键入的 out/pasted URL(未嵌入到文本中)。
对于 link 使用 React 函数式编程的人,有没有人有实际工作示例或我可能做错的建议?
事实证明,我需要添加装饰器才能检测到实体。我放置了我的编辑器组件的代码 above/outside:
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,
},
]);
基本上,它会检测 link 个实体,并在您使用 EditorState 设置新内容时将它们转换为元素:
const newState = EditorState.set(editorState, {
currentContent: styledContentStateWithLink,
decorator: strategyDecorator
});
根据 official example 你需要添加一个装饰器来找到实体并应用 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
我已经研究这个问题一段时间了,希望这不是一个错误。
我正在使用 Draft.js 测试一个文本编辑器,我只是希望我的用户在他们的文章中添加一个 hyperlink,所以我创建了一个函数来实现它修改编辑器状态的内容。
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 对象实现的样式有效,但我似乎无法使 link 实际起作用。应该注意的是,link 插件作为一个包,效果很好,但这仅用于检测键入的 out/pasted URL(未嵌入到文本中)。
对于 link 使用 React 函数式编程的人,有没有人有实际工作示例或我可能做错的建议?
事实证明,我需要添加装饰器才能检测到实体。我放置了我的编辑器组件的代码 above/outside:
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,
},
]);
基本上,它会检测 link 个实体,并在您使用 EditorState 设置新内容时将它们转换为元素:
const newState = EditorState.set(editorState, {
currentContent: styledContentStateWithLink,
decorator: strategyDecorator
});
根据 official example 你需要添加一个装饰器来找到实体并应用 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