Buat semula fungsi untuk rekod entiti tidak menetapkan status dengan betul
P粉029057928
P粉029057928 2023-09-15 19:27:41
0
1
778

Saya sedang membina aplikasi peta minda menggunakan rekod entiti. Data dalam aplikasi adalah pepohon nod dan saya mahu dapat membuat semula nod melalui buat asal/buat semula. Masalah yang saya hadapi ialah walaupun operasi buat asal berfungsi dengan baik, operasi buat semula tidak.

Saya mencipta semula masalah saya dalam aplikasi mudah:

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;

Apabila butang "Tukar ibu bapa 3" diklik, fungsi changeState:

  1. Alih keluar nod 3 daripada senarai anak induknya (nod 0)
  2. Tambah nod 3 pada senarai nod anak nod induk (nod 2) baharunya
  3. Tetapkan semula nod induk nod 3 kepada 2

Rework betul memulihkan keadaan kepada nilai awalnya, dengan lajur 1,2,3 adalah anak 0.

Tetapi Buat Semula menetapkan senarai nod anak nod 0 hingga 3 apabila ia sepatutnya menetapkannya kepada 1,2! Sangat pelik, ini tidak berlaku jika saya tidak menetapkan sifat Parentis nod 3, yang tidak berkaitan secara langsung dengan sifat Kanak-kanak nod 0...

Saya mengesyaki ini ialah isu rujukan vs jenis nilai, atau mungkin pepijat dalam rekod entiti... Sebarang bantuan?

P粉029057928
P粉029057928

membalas semua(1)
P粉729518806

Seperti yang saya syak, soalan itu adalah soalan rujukan... Apabila melakukan operasi pertama, gunakan fungsi "cari" n => n.id === node.parentid untuk memilih elemen tatasusunan yang betul. Walau bagaimanapun, cara rekod pepejal menyimpan sejarah arahan adalah sedemikian rupa sehingga ia hanya menyimpan objek "nod". Dan sifat induk bagi objek yang sama diubah suai oleh operasi terakhir. Masalah telah diselesaikan dengan menggunakan pembolehubah tempatan yang menyimpan node.parentid.

Atau, selepas membaca dokumentasi API kedai SolidJS dengan lebih baik, gunakan id secara langsung dan bukannya fungsi carian, seperti:

undoHistory.add(setState, node.parentid, 'children', oldparent.children.filter(n => n !== node.id))
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan