0

我想让我的文本编辑器显示通过键盘命令选择并执行了多少次内容块。我通过将实体应用到具有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";
    }
  };
}

4

2 回答 2

0

根据这个(https://github.com/facebook/draft-js/issues/1702),您还可以更新选择状态,这对您来说可能就足够了。

于 2021-01-14T23:40:26.320 回答
0

为我工作:

function forceRerender(editorState: EditorState): EditorState {
    const selectionState = editorState.getSelection();
    return EditorState.forceSelection(editorState, selectionState);
}
于 2021-07-22T08:28:41.580 回答