DraftJs:使用实体键替换实体



我正在使用draftjs创建一个富文本编辑器,但找不到任何资源来帮助我解决问题。

请先查看代码沙盒。

您可以看到包含链接的文本(红色的testtest(。如果你点击它,你会看到表中链接的一些信息:

| 🔗 link src         | http://localhost:8080/testtest |
| 📝 link text        | testtest                       |
| 🔑 link Entity key  | ab5a7c6d...                    |

我获取当前链接密钥(🔑)感谢我的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助手获得链接Entity

const getCurrentLinkEntity = (
editorState: EditorState
): EntityInstance | null => {
const contentState = editorState.getCurrentContent();
const linkKey = getCurrentLinkKey(editorState, contentState);
if (linkKey) {
return contentState.getEntity(linkKey);
}
return null;
};

使用链路Entity,我最终可以得到srctext的值:

getCurrentLinkEntity(editorState).getData().url   // 🔗
getCurrentLinkEntity(editorState).getData().text  // 📝

您可以在底部看到一个按钮Insert link。如果选择整个链接testtest并单击此按钮,则该链接将被替换。

此功能由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")
);
};

但这个功能只会用谷歌链接替换你选择的文本。我想要的是,如果你在一个链接上点击按钮,那么整个链接都应该更新。所以我创造了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助手(,链接不会更新,但srctext是空的:

| 🔗 link src         |             |
| 📝 link text        |             |
| 🔑 link Entity key  | a1e34047... |

那么,作为一个有想法的人,我如何使用它的实体密钥来替换链接Entity

我给出了一个答案,使用draftjs-utils包并替换链接,但不使用其实体键

这个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")
);
};

检查代码沙盒以查看其实时运行。

最新更新