實體記錄的重做功能未正確設定狀態
P粉029057928
P粉029057928 2023-09-15 19:27:41
0
1
717

我正在使用實體記錄來建立心智圖應用程式。 應用程式中的資料是一棵節點樹,我希望能夠透過撤銷/重做來重新設定節點的父級。 我面臨的問題是,即使撤銷操作工作正常,但重做操作卻不行。

我在一個簡單的應用程式中重新創建了我的問題:

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;

當點擊「更改 3 的父級」按鈕時,changeState 函數:

  1. 從其父級(節點 0)子級清單中刪除節點 3
  2. 將節點 3 新增到其新的父節點(節點 2)子節點清單
  3. 將節點 3 的父節點重設為 2

重做正確地將狀態恢復到其初始值,其中 1,2,3 列為 0 的子級。

但是 Redo 將節點 0 的子節點清單設為 3,而它應該將其設為 1,2! 非常奇怪的是,如果我不設定節點 3 的 Parentis 屬性,則不會發生這種情況,該屬性與節點 0 的 Children 屬性沒有直接關係...

我懷疑這是一個引用與值類型的問題,或者可能是實體記錄中的錯誤... 有什麼幫助嗎?

P粉029057928
P粉029057928

全部回覆(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))
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!