javascript - DraftJs: แทนที่เอนทิตีโดยใช้คีย์เอนทิตีของมัน
ฉันกำลังสร้างตัวแก้ไขข้อความแบบรวยด้วย draftjs และไม่สามารถหาทรัพยากรใด ๆ ที่จะช่วยฉันในปัญหาของฉันได้
กรุณาดูก่อนที่ codesandbox
คุณสามารถเห็นข้อความที่มีลิงก์ (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);
};
แล้วด้วยกุญแจนี้ฉันสามารถรับลิงก์ Entity โดยใช้ตัวช่วย getCurrentLinkEntity:
const getCurrentLinkEntity = (
editorState: EditorState
): EntityInstance | null => {
const contentState = editorState.getCurrentContent();
const linkKey = getCurrentLinkKey(editorState, contentState);
if (linkKey) {
return contentState.getEntity(linkKey);
}
return null;
};
โดยใช้ลิงก์ Entity ฉันสามารถรับค่า src และ text ได้ในที่สุด:
getCurrentLinkEntity(editorState).getData().url // 🔗
getCurrentLinkEntity(editorState).getData().text // 📝
คุณสามารถเห็นที่ด้านล่างมีปุ่ม แทรกลิงก์ หากคุณเลือกทั้งลิงก์ 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")
);
};
แต่ว่าฟังก์ชันนี้จะทำเพียงแค่แทนที่ข้อความที่คุณเลือกด้วยลิงก์ของ Google สิ่งที่ฉันต้องการคือ ถ้าคุณอยู่บนลิงก์แล้วกดปุ่ม ลิงก์ทั้งลิงก์ควรถูกอัปเดต ดังนั้นฉันจึงสร้างตัวช่วย 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) ลิงก์จะไม่ถูกอัปเดต แต่ src และ text จะว่าง:
| 🔗 link src | |
| 📝 link text | |
| 🔑 link Entity key | a1e34047... |
ดังนั้นมีใครมีไอเดียว่าฉันสามารถแทนที่ลิงก์ Entity โดยใช้คีย์เอนทิตีของมันได้อย่างไร?
คำตอบ #1
เอาล่ะ ผมมีคำตอบที่ใช้แพ็กเกจ 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")
);
};
ตรวจสอบ codesandbox เพื่อดูแบบสด
