Die Redo-Funktion für Entitätsdatensätze setzt den Status nicht korrekt
P粉029057928
P粉029057928 2023-09-15 19:27:41
0
1
783

Ich erstelle eine Mindmapping-Anwendung unter Verwendung von Entitätsdatensätzen. Die Daten in der Anwendung sind ein Knotenbaum und ich möchte die Knoten über Rückgängig/Wiederherstellen neu anordnen können. Das Problem, mit dem ich konfrontiert bin, besteht darin, dass der Rückgängig-Vorgang zwar einwandfrei funktioniert, der Wiederherstellungs-Vorgang jedoch nicht.

Ich habe mein Problem in einer einfachen App nachgestellt:

import { Component, For } from 'solid-js'
import { createStore } from 'solid-js/store'
import { createHistory } from 'solid-record'

type Node = {
  id: number,
  children: Array<number>
  parentid: number
}

const initialValue = [
  { id: 0, children: [1, 2, 3], parentid: -1 },
  { id: 1, children: [], parentid: 0 },
  { id: 2, children: [], parentid: 0 },
  { id: 3, children: [], parentid: 0 },
]

const [state, setState] = createStore(initialValue)
const undoHistory = createHistory()

const changeState = () => {
  undoHistory.batch()

  const nodeid = 3
  const oldparentid = 0
  const newparentid = 2
  let node = state[nodeid]
  let oldparent = state[oldparentid]
  let newparent = state[newparentid]

  // first remove node form parent's children
  undoHistory.add(setState, n => n.id === node.parentid, 'children', oldparent.children.filter(n => n !== node.id))
  // then add to new parent's children
  undoHistory.add(setState, n => n.id === newparent.id, 'children', [...newparent.children, node.id])
  // lastly, point to new parent
  undoHistory.add(setState, n => n.id === node.id, 'parentid', newparent.id)
  undoHistory.unbatch()
}

const App: Component = () => {
  return (
    <>
      <For each={state}>{(node: Node) => <div>{`id: ${node.id}, parentid: ${node.parentid}, children: ${node.children}`}</div>}</For>
      <button onClick={changeState}>Change Parent of 3</button>
      <button onClick={() => undoHistory.undo()} disabled={!undoHistory.isUndoable()}>Undo</button>
      <button onClick={() => undoHistory.redo()} disabled={!undoHistory.isRedoable()}>Redo</button>
    </>
  );
};

export default App;

Wenn auf die Schaltfläche „Übergeordnetes Element von 3 ändern“ geklickt wird, wird die Funktion „changeState“ ausgeführt:

  1. Entfernen Sie Knoten 3 aus der Liste seiner übergeordneten (Knoten 0) untergeordneten Elemente
  2. Fügen Sie Knoten 3 zur Liste der untergeordneten Knoten seines neuen übergeordneten Knotens (Knoten 2) hinzu
  3. Setzen Sie den übergeordneten Knoten von Knoten 3 auf 2 zurück

Rework stellt den Status korrekt auf seinen Anfangswert wieder her, wobei die Spalten 1,2,3 untergeordnete Elemente von 0 sind.

Aber Redo setzt die untergeordnete Knotenliste von Knoten 0 auf 3, obwohl es sie auf 1,2 setzen sollte! Seltsamerweise passiert dies nicht, wenn ich die Parentis-Eigenschaft von Knoten 3 nicht setze, die nicht direkt mit der Children-Eigenschaft von Knoten 0 zusammenhängt...

Ich vermute, dass es sich hierbei um ein Problem mit der Referenz oder dem Werttyp oder vielleicht um einen Fehler im Entitätsdatensatz handelt ... Irgendeine Hilfe?

P粉029057928
P粉029057928

Antworte allen(1)
P粉729518806

正如我所怀疑的,该问题是参考问题...... 执行第一个操作时,使用“搜索”函数 n => n.id === node.parentid 选择数组的正确元素。 但是,solid-record 存储命令历史的方式使得它只存储“节点”对象。 并且同一对象的parentid 属性被最后一个操作修改。 通过使用存储node.parentid的局部变量解决了该问题。

或者,在更好地阅读 SolidJS store API 文档之后,直接使用 id 而不是搜索功能,例如:

undoHistory.add(setState, node.parentid, 'children', oldparent.children.filter(n => n !== node.id))
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage