cari

Rumah  >  Soal Jawab  >  teks badan

Buat semula fungsi untuk rekod entiti tidak menetapkan status dengan betul

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粉029057928P粉029057928436 hari yang lalu780

membalas semua(1)saya akan balas

  • P粉729518806

    P粉7295188062023-09-16 11:56:23

    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))

    balas
    0
  • Batalbalas