DraftJs:使用实体键替换实体
DraftJs: Replace an entity using its entity key
我正在使用 draftjs 创建一个富文本编辑器,但找不到任何资源来帮助我解决我的问题。
请先看看codesandbox。
您可以看到包含 link(红色的 testtest
)的文本。如果你点击它,你会在 table:
中看到 link 的一些信息
| link src | http://localhost:8080/testtest |
| link text | testtest |
| link Entity key | ab5a7c6d... |
我得到了当前的 link 键 () 感谢我的 getCurrentLinkKey
助手:
const getCurrentLinkKey = (
editorState: EditorState,
contentState?: ContentState
): string => {
if (contentState === undefined) {
contentState = editorState.getCurrentContent();
}
const startKey = editorState.getSelection().getStartKey();
const startOffset = editorState.getSelection().getStartOffset();
const blockWithLinkAtBeginning = contentState.getBlockForKey(startKey);
return blockWithLinkAtBeginning.getEntityAt(startOffset);
};
然后使用此密钥,我可以使用 getCurrentLinkEntity
帮助程序获得 link Entity
:
const getCurrentLinkEntity = (
editorState: EditorState
): EntityInstance | null => {
const contentState = editorState.getCurrentContent();
const linkKey = getCurrentLinkKey(editorState, contentState);
if (linkKey) {
return contentState.getEntity(linkKey);
}
return null;
};
使用 link Entity
我终于可以得到 src
和 text
值:
getCurrentLinkEntity(editorState).getData().url //
getCurrentLinkEntity(editorState).getData().text //
您可以在底部看到一个按钮 Insert link
。如果您 select 整个 link testtest
并单击此按钮,link 将被替换。
此功能由 insertLink
助手处理:
const insertLink = (
link: string,
text: string,
editorState: EditorState,
setEditorState: (editorState: EditorState) => void
): void => {
const contentStateWithEntity = editorState
.getCurrentContent()
.createEntity("LINK", "MUTABLE", { url: link, text });
const entityKey = contentStateWithEntity.getLastCreatedEntityKey();
const contentState = Modifier.replaceText(
editorState.getCurrentContent(),
editorState.getSelection(),
text,
editorState.getCurrentInlineStyle(),
entityKey
);
const newEditorState = EditorState.set(editorState, {
currentContent: contentStateWithEntity
});
const newEditorStateWithLink = RichUtils.toggleLink(
newEditorState,
newEditorState.getSelection(),
entityKey
);
setEditorState(
EditorState.push(newEditorStateWithLink, contentState, "insert-characters")
);
};
但此函数只会用 google link 替换您的 selected 文本。我想要的是,如果您在 link 上并单击按钮,那么应该更新整个 link。所以我创造了
replaceLink
助手:
const replaceLink = (
link: string,
text: string,
editorState: EditorState,
setEditorState: (editorState: EditorState) => void
): void => {
const contentStateWithEntity = editorState
.getCurrentContent()
.createEntity("LINK", "MUTABLE", { url: link, text });
const entityKey = contentStateWithEntity.getLastCreatedEntityKey();
const newEditorState = EditorState.set(editorState, {
currentContent: contentStateWithEntity
});
const contentState = newEditorState
.getCurrentContent()
.replaceEntityData(getCurrentLinkKey(editorState), { entityKey });
const newEditorStateWithLink = RichUtils.toggleLink(
newEditorState,
newEditorState.getSelection(),
entityKey
);
setEditorState(
EditorState.push(newEditorStateWithLink, contentState, "insert-characters")
);
};
但遗憾的是,如果我单击 Replace link
按钮(触发 replaceLink
助手),link 不会更新,但 src
和 text
为空:
| link src | |
| link text | |
| link Entity key | a1e34047... |
所以有人知道如何使用它的实体密钥替换 link Entity
?
我的答案是使用 draftjs-utils 包并替换 link 但不使用其实体键 :
这个 replaceLink
助手的灵感来自 react-draft-wysiwyg 图书馆的作品:
export const replaceLink = (
link: string,
text: string,
editorState: EditorState,
setEditorState: (editorState: EditorState) => void
): void => {
const currentContent = editorState.getCurrentContent();
// Create new link entity
const contentStateWithEntity = currentContent.createEntity(
"LINK",
"MUTABLE",
{ url: link, text }
);
// Get created link entity's key
const entityKey = contentStateWithEntity.getLastCreatedEntityKey();
let selection = editorState.getSelection();
const entityRange = getEntityRange(
editorState,
getSelectionEntity(editorState)
);
const isBackward = selection.getIsBackward();
if (isBackward) {
selection = selection.merge({
anchorOffset: entityRange.end,
focusOffset: entityRange.start
});
} else {
selection = selection.merge({
anchorOffset: entityRange.start,
focusOffset: entityRange.end
});
}
const updatedEditorWithText = Modifier.replaceText(
currentContent,
selection,
text,
editorState.getCurrentInlineStyle(),
entityKey
);
const newEditorState = EditorState.push(
editorState,
updatedEditorWithText,
"insert-characters"
);
setEditorState(
EditorState.push(newEditorState, updatedEditorWithText, "insert-characters")
);
};
点击 codesandbox 观看直播。
我正在使用 draftjs 创建一个富文本编辑器,但找不到任何资源来帮助我解决我的问题。
请先看看codesandbox。
您可以看到包含 link(红色的 testtest
)的文本。如果你点击它,你会在 table:
| link src | http://localhost:8080/testtest |
| link text | testtest |
| link Entity key | ab5a7c6d... |
我得到了当前的 link 键 () 感谢我的 getCurrentLinkKey
助手:
const getCurrentLinkKey = (
editorState: EditorState,
contentState?: ContentState
): string => {
if (contentState === undefined) {
contentState = editorState.getCurrentContent();
}
const startKey = editorState.getSelection().getStartKey();
const startOffset = editorState.getSelection().getStartOffset();
const blockWithLinkAtBeginning = contentState.getBlockForKey(startKey);
return blockWithLinkAtBeginning.getEntityAt(startOffset);
};
然后使用此密钥,我可以使用 getCurrentLinkEntity
帮助程序获得 link Entity
:
const getCurrentLinkEntity = (
editorState: EditorState
): EntityInstance | null => {
const contentState = editorState.getCurrentContent();
const linkKey = getCurrentLinkKey(editorState, contentState);
if (linkKey) {
return contentState.getEntity(linkKey);
}
return null;
};
使用 link Entity
我终于可以得到 src
和 text
值:
getCurrentLinkEntity(editorState).getData().url //
getCurrentLinkEntity(editorState).getData().text //
您可以在底部看到一个按钮 Insert link
。如果您 select 整个 link testtest
并单击此按钮,link 将被替换。
此功能由 insertLink
助手处理:
const insertLink = (
link: string,
text: string,
editorState: EditorState,
setEditorState: (editorState: EditorState) => void
): void => {
const contentStateWithEntity = editorState
.getCurrentContent()
.createEntity("LINK", "MUTABLE", { url: link, text });
const entityKey = contentStateWithEntity.getLastCreatedEntityKey();
const contentState = Modifier.replaceText(
editorState.getCurrentContent(),
editorState.getSelection(),
text,
editorState.getCurrentInlineStyle(),
entityKey
);
const newEditorState = EditorState.set(editorState, {
currentContent: contentStateWithEntity
});
const newEditorStateWithLink = RichUtils.toggleLink(
newEditorState,
newEditorState.getSelection(),
entityKey
);
setEditorState(
EditorState.push(newEditorStateWithLink, contentState, "insert-characters")
);
};
但此函数只会用 google link 替换您的 selected 文本。我想要的是,如果您在 link 上并单击按钮,那么应该更新整个 link。所以我创造了
replaceLink
助手:
const replaceLink = (
link: string,
text: string,
editorState: EditorState,
setEditorState: (editorState: EditorState) => void
): void => {
const contentStateWithEntity = editorState
.getCurrentContent()
.createEntity("LINK", "MUTABLE", { url: link, text });
const entityKey = contentStateWithEntity.getLastCreatedEntityKey();
const newEditorState = EditorState.set(editorState, {
currentContent: contentStateWithEntity
});
const contentState = newEditorState
.getCurrentContent()
.replaceEntityData(getCurrentLinkKey(editorState), { entityKey });
const newEditorStateWithLink = RichUtils.toggleLink(
newEditorState,
newEditorState.getSelection(),
entityKey
);
setEditorState(
EditorState.push(newEditorStateWithLink, contentState, "insert-characters")
);
};
但遗憾的是,如果我单击 Replace link
按钮(触发 replaceLink
助手),link 不会更新,但 src
和 text
为空:
| link src | |
| link text | |
| link Entity key | a1e34047... |
所以有人知道如何使用它的实体密钥替换 link Entity
?
我的答案是使用 draftjs-utils 包并替换 link 但不使用其实体键 :
这个 replaceLink
助手的灵感来自 react-draft-wysiwyg 图书馆的作品:
export const replaceLink = (
link: string,
text: string,
editorState: EditorState,
setEditorState: (editorState: EditorState) => void
): void => {
const currentContent = editorState.getCurrentContent();
// Create new link entity
const contentStateWithEntity = currentContent.createEntity(
"LINK",
"MUTABLE",
{ url: link, text }
);
// Get created link entity's key
const entityKey = contentStateWithEntity.getLastCreatedEntityKey();
let selection = editorState.getSelection();
const entityRange = getEntityRange(
editorState,
getSelectionEntity(editorState)
);
const isBackward = selection.getIsBackward();
if (isBackward) {
selection = selection.merge({
anchorOffset: entityRange.end,
focusOffset: entityRange.start
});
} else {
selection = selection.merge({
anchorOffset: entityRange.start,
focusOffset: entityRange.end
});
}
const updatedEditorWithText = Modifier.replaceText(
currentContent,
selection,
text,
editorState.getCurrentInlineStyle(),
entityKey
);
const newEditorState = EditorState.push(
editorState,
updatedEditorWithText,
"insert-characters"
);
setEditorState(
EditorState.push(newEditorState, updatedEditorWithText, "insert-characters")
);
};
点击 codesandbox 观看直播。