reactjs - 如何在 Draft-JS 中添加链接(无插件)
问题描述
我正在尝试创建一个按钮,onClick 将为您提供放置链接的选项,然后此链接必须在文本字段中显示为标签。到目前为止,我设法添加和显示纯文本,但我不知道如何将其转换为标签。
// Link function
const addLinkFn = (editorState, link) => {
const contentState = editorState.getCurrentContent();
const contentStateWithEntity = contentState.createEntity(
"LINK",
"IMMUTABLE",
{ url: link }
);
const entityKey = contentStateWithEntity.getLastCreatedEntityKey();
const newEditorState = EditorState.set(editorState, {
currentContent: contentStateWithEntity,
});
return AtomicBlockUtils.insertAtomicBlock(newEditorState, entityKey, link);
};
const onAddLink = () => {
let link = window.prompt("Add link http:// ");
const newEditorState = addLinkFn(editorState, link);
setEditorState(newEditorState);
};
我知道在某个地方我必须有这样的“装饰器”和“策略”:
const linkStrategy = (contentBlock, callback, contentState) => {
contentBlock.findEntityRanges((character) => {
const entityKey = character.getEntity();
return (
entityKey !== null &&
contentState.getEntity(entityKey).getType() === "LINK"
);
}, callback);
};
const Link = (props) => {
const { contentState, entityKey } = props;
const { url } = contentState.getEntity(entityKey).getData();
return (
<a
className="link"
href={url}
rel="noopener noreferrer"
target="_blank"
aria-label={url}
>
{props.children}
</a>
);
};
然后像这样声明它们:
decorators: [
{
strategy: linkStrategy,
component: Link,
},
],
只是我不确定如何将所有东西放在一起以使其正常工作:D 谢谢!
解决方案
我想到了。整个组件如下所示:
//Add Link Component
import React from "react";
import { CompositeDecorator, EditorState, Modifier } from "draft-js";
const Link = ({ entityKey, contentState, children }) => {
let { url } = contentState.getEntity(entityKey).getData();
return (
<a
style={{ color: "blue", fontStyle: "italic" }}
href={url}
target="_blank"
>
{children}
</a>
);
};
const findLinkEntities = (contentBlock, callback, contentState) => {
contentBlock.findEntityRanges((character) => {
const entityKey = character.getEntity();
return (
entityKey !== null &&
contentState.getEntity(entityKey).getType() === "LINK"
);
}, callback);
};
export const createLinkDecorator = () =>
new
CompositeDecorator
([
{
strategy: findLinkEntities,
component: Link,
},
]);
// call all together
export const onAddLink = (editorState, setEditorState) => {
let linkUrl = window.prompt("Add link http:// ");
const decorator = createLinkDecorator();
if (linkUrl) {
let displayLink = window.prompt("Display Text");
if (displayLink) {
const currentContent = editorState.getCurrentContent();
const createEntity = currentContent.createEntity("LINK", "MUTABLE", {
url: linkUrl,
});
let entityKey = currentContent.getLastCreatedEntityKey();
const selection = editorState.getSelection();
const textWithEntity = Modifier.insertText(
currentContent,
selection,
displayLink,
null,
entityKey
);
let newState = EditorState.createWithContent(textWithEntity, decorator);
setEditorState(newState);
}
}
};
然后你必须将它附加到编辑器工具栏(如果你有一个:
import { onAddLink } from "./Link";
<button
onClick={() => onAddLink(props.editorState, props.setEditorState)}
>
link
</button>
然后在编辑器的显示部分引用 deocrator,以便它知道链接的样子:
import { createLinkDecorator } from "./Components/Link";
const decorator = createLinkDecorator();
const editorState = props.postData
? EditorState.createWithContent(convertFromRaw(props.postData),
// add the decorator after the state
decorator
)
: EditorState.createEmpty();
推荐阅读
- python - FAIL : NameError: name 'urlparse' 未定义
- typescript - 使用带有方法的索引签名 - Typescript 3.5
- vim - vim 帮助产生“无法打开交换文件”错误
- javascript - “访问控制允许来源”:“*”不起作用
- php - 如何一次循环通过某个数字$ wpdb结果php wordpress
- ruby-on-rails - 如果用户已注册该帖子,则检查用户是否可以在帖子中发表评论
- ruby-on-rails - Rspec:期望“超级”被调用
- javascript - 如何避免与 getstream-cli 冲突的终端命令?
- reactjs - 试图窥探一个模拟函数
- google-cloud-platform - 如何在 Google Cloud 上查看 VM 实例的磁盘使用情况?