我想让我的文本编辑器显示通过键盘命令选择并执行了多少次内容块。我通过将实体应用到具有evaluatedTimes
属性的选定块来做到这一点。数据已正确更改,但实体组件不会重新渲染,直到我在文本块中插入新字符。
实体的装饰器策略没有被调用,所以我找到的唯一方法是使用新的装饰器实例更新编辑器状态。这样实体组件会被重新渲染,但解决方案有点hacky。
依赖项:
"draft-js": "^0.11.3",
"draft-js-plugins-editor": "^3.0.0",
"draftjs-utils": "^0.10.2"
代码:
// plugin.js
import { EditorState } from "draft-js";
import { getSelectionText, getSelectionEntity } from "draftjs-utils";
import { EvaluatedSpan } from "./components";
import { findEvaluatedEntities, createEvaluatedEntity } from "./entities";
export function createCodeEvaluationPlugin({ onEvaluate = () => {} }) {
return {
decorators: [
{
strategy: findEvaluatedEntities,
component: EvaluatedSpan
}
],
keyBindingFn: e => {
// CMD + ENTER
if (e.metaKey && e.keyCode === 13) {
return "evaluate";
}
},
handleKeyCommand: (command, editorState, _, { setEditorState }) => {
if (command === "evaluate") {
const selectionState = editorState.getSelection();
const contentState = editorState.getCurrentContent();
const entityKey = getSelectionEntity(editorState);
// If selection contains an entity:
if (!entityKey) {
// Create new entity and update editor.
setEditorState(createEvaluatedEntity(editorState, selectionState));
} else {
// Modify entity data.
const entity = contentState.getEntity(entityKey);
const nextContentState = contentState.mergeEntityData(entityKey, {
evaluatedTimes: entity.data.evaluatedTimes + 1
});
// Update editor.
setEditorState(
EditorState.push(editorState, nextContentState, "change-block-data")
);
}
// Pass text to callback handle
const selectionText = getSelectionText(editorState);
onEvaluate(selectionText);
return "handled";
}
return "not-handled";
}
};
}