Не удалось заставить цитоскейп отменить-повторить работу правильно

Я использую Cytoscape и пытаюсь запустить его, как это демо . Я преобразовал большую часть кода в React, и он в основном работает.

Проблема, с которой я столкнулся, заключается в том, чтобы заставить CTRL+Z работать так же, как в демоверсии (или любой другой ввод с клавиатуры, если на то пошло). Я знаю, что я правильно зарегистрировал плагин, потому что я могу программно отменить и повторить действия с помощью действий undo() и redo().

Я не уверен, что здесь происходит, возможно, это проблема с React?

В песочнице видно, что кнопки undo и redo работают нормально, а вот клавиатура CTRL+Z и CTRL+Y — нет. Почему привязки клавиатуры работают в их демо, а не в моей песочнице?

Вот что у меня есть,

import React from "react";
import cytoscape, { Core as CSCore } from "cytoscape";
import CytoscapeComponent from "react-cytoscapejs";
import stylesheet from "./stylesheet";
import layout from "./layout";
import { initialNodes, initialEdges } from "./elements";
import { TEdge } from "./elements/edges";
import { TNode } from "./elements/nodes";

import undoRedo from "cytoscape-undo-redo";

cytoscape.use(undoRedo);

export default React.memo(() => {
  // Nodes and edges are handles separately
  const [nodes] = React.useState<TNode[]>(initialNodes);
  const [edges] = React.useState<TEdge[]>(initialEdges);

  // Cytoscape instance
  const cyRef = React.useRef<CSCore | null>(null);
  // UndoRedo instance
  const urRef = React.useRef<any>(null);

  const init = React.useCallback((cy: CSCore) => {
    if (!cyRef.current) {
      cyRef.current = cy;
    }

    urRef.current = cyRef.current.undoRedo({
      isDebug: false, // Debug mode for console messages
      actions: {}, // actions to be added
      undoableDrag: true, // Whether dragging nodes are undoable can be a function as well
      stackSizeLimit: undefined, // Size limit of undo stack, note that the size of redo stack cannot exceed size of undo stack
      ready: function () {
        // callback when undo-redo is ready
      }
    }); // Can also be set whenever wanted.

    cyRef.current.on("afterUndo", function (e, name) {
      // @ts-ignore
      document.getElementById("undos").innerHTML +=
        "<span style='color: darkred; font-weight: bold'>Undo: </span> " +
        name +
        "</br>";
    });

    cyRef.current.on("afterRedo", function (e, name) {
      // @ts-ignore
      document.getElementById("undos").innerHTML +=
        "<span style='color: darkblue; font-weight: bold'>Redo: </span>" +
        name +
        "</br>";
    });

    cyRef.current.on("afterDo", function (e, name) {
      // @ts-ignore
      document.getElementById("undos").innerHTML +=
        "<span style='color: darkmagenta; font-weight: bold'>Do: </span>" +
        name +
        "</br>";
    });
  }, []);

  return (
    <div>
      <div id = "undoRedoList">
        <span style = {{ color: "darkslateblue", fontWeight: "bold" }}>Log</span>
        <div
          id = "undos"
          style = {{ paddingBottom: 20, position: "absolute", left: 40, top: 40 }}
        />
      </div>
      <div
        style = {{ zIndex: 99999999, position: "absolute", right: 20, top: 20 }}
      >
        <button onClick = {() => urRef.current.undo()}>undo</button>
        <button onClick = {() => urRef.current.redo()}>redo</button>
      </div>
      <CytoscapeComponent
        elements = {CytoscapeComponent.normalizeElements({
          nodes: nodes,
          edges: edges
        })}
        layout = {layout}
        cy = {(cy) => init(cy)}
        stylesheet = {stylesheet}
        style = {{
          width: "100vw",
          height: "100vh"
        }}
      />
    </div>
  );
});
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
0
444
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Единственное, что не так с вашим кодом, это отсутствие реальных ключевых слушателей. В демо-версии отмены и повтора функции crtl+z и crtl+y на самом деле таковы:

document.addEventListener("keydown", function(e) {
  if (e.which === 46) {
    var selecteds = cy.$(":selected");
    if (selecteds.length > 0)
      ur.do("remove", selecteds);
  } else if (e.ctrlKey && e.target.nodeName === 'BODY')
    if (e.which === 90)
      ur.undo();
    else if (e.which === 89)
    ur.redo();
});

Если вы вставите это в свой код (я попробовал это после вашего прослушивателя событий «afterDo» в «index.tsx», тогда ваш откат-повтор должен работать правильно. У меня была одна проблема, когда ваш код жаловался на то, что отмена-повтор определен дважды, но это решилось само собой после перезагрузки вашей песочницы.

Другие вопросы по теме