如何将数组与foreach一起与foreach一起使用creatememo maparray显示以显示在顶部的拖动项目

发布于 2025-01-31 00:41:10 字数 1587 浏览 2 评论 0原文

我正在尝试显示拖放物品在顶部的列表。 我对嵌套在createMemo maparray的列表进行了排序。 就我而言,它可以用这个示例来复制它。

#1问题,为什么此示例不排序并在顶部显示拖动项目。 createEfect console.log m_atoms_sorted也不会retrigger,即使它触及了每个原子的.dragging信号。

#2问题,就我而言,但是当我尝试通过setList1从原始数组中删除项目时,就会发生问题。在这种情况下,list1正确更新,但它显示为旧项目并删除错误的项目。

如果我删除了问题的消失。

import { render } from "solid-js/web";
import { For, createSignal, createMemo, mapArray, createEffect } from "solid-js";

const make_atom = (n) => {
   let [_dragging, _setDragging] = createSignal(false)

   return {
      n,
      get dragging() { return _dragging() },
      set dragging(v: boolean) { _setDragging(v) }
   }
}

function Counter() {
  const [list1, setList1] = createSignal([1, 2, 3, 4, 5]);
  
  const m_atoms = createMemo(mapArray(list1, make_atom))

  const m_atoms_sorted = createMemo(() => {
     return m_atoms()
      .sort((a, b) => a.dragging ? (b.dragging ? 0 : 1) : (b.dragging ? -1 : 0))
  })
  createEffect(() => {
     console.log(m_atoms().map(_ => _.dragging).join(''))
  })
  createEffect(() => {
  console.log(m_atoms_sorted())
  })

  return (<>
    <For each={m_atoms_sorted()}>{ item => 
       <span onClick={_ => item.dragging = !item.dragging}>|{item.n}{item.dragging ? 'drag':'nodrag'}|</span>
    }</For>
    </>)
}

render(() => <Counter />, document.getElementById("app"));

编辑

确定,如果我删除m_atoms_sorted的createMeMo,它将拖动项目正确。所以我的问题是#2。

I am trying to display a list where dragged item is on top.
I sorted the list thats nested inside createMemo mapArray.
It works in my case, but I couldn't reproduce it with this example.

#1 Problem, why doesnt this example sort and display the dragged items on top. Also createEffect console.log m_atoms_sorted doesn't retrigger even though it touches the .dragging signal of every atom.

#2 Problem, in my case it sorts, but the problem occurs when I try to remove an item from the original array via setList1. In that case list1 correctly updates, but it display's the old items and removes the wrong item.

If I remove the sort the problem dissapears.

import { render } from "solid-js/web";
import { For, createSignal, createMemo, mapArray, createEffect } from "solid-js";

const make_atom = (n) => {
   let [_dragging, _setDragging] = createSignal(false)

   return {
      n,
      get dragging() { return _dragging() },
      set dragging(v: boolean) { _setDragging(v) }
   }
}

function Counter() {
  const [list1, setList1] = createSignal([1, 2, 3, 4, 5]);
  
  const m_atoms = createMemo(mapArray(list1, make_atom))

  const m_atoms_sorted = createMemo(() => {
     return m_atoms()
      .sort((a, b) => a.dragging ? (b.dragging ? 0 : 1) : (b.dragging ? -1 : 0))
  })
  createEffect(() => {
     console.log(m_atoms().map(_ => _.dragging).join(''))
  })
  createEffect(() => {
  console.log(m_atoms_sorted())
  })

  return (<>
    <For each={m_atoms_sorted()}>{ item => 
       <span onClick={_ => item.dragging = !item.dragging}>|{item.n}{item.dragging ? 'drag':'nodrag'}|</span>
    }</For>
    </>)
}

render(() => <Counter />, document.getElementById("app"));

Edit

Ok, If I remove the createMemo for m_atoms_sorted, it correctly puts dragging items on top. So my problem is #2.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

冰魂雪魄 2025-02-07 00:41:10

示例中的组件逻辑还不够清晰,但是maparrayindexArray在内部进行备忘录,因此您不必预先进行。

如果将它们存储在信号中并相应地更新订单,则可以更轻松地重新排序。

// Swap the elements in place and return a new array
// otherwise signal will not update.
function swapElements(arr: Array<any>, a: number, b: number) {
  let temp = arr[a];
  arr[a] = arr[b];
  arr[b] = temp;
  return [...arr];
};

const initialVal = Array.from({ length: 10 }, ((v, i) => `Item #${i}`));

const App = () => {
  const [items, setItems] = createSignal(initialVal);
  const [prevPos, setPrevPos] = createSignal(0);

  const handleStart = (event: MouseEvent) => {
    setPrevPos(event.target.dataset.order);
  };

  const handleDrop = (event: MouseEvent) => {
    event.preventDefault();
    const nextPos = event.target.dataset.order;
    const arr = swapElements(items(), nextPos, prevPos());
    setItems(arr);
  };

  const handleDragOver = (event: MouseEvent) => {
    event.preventDefault();
  };


  return (
    <ul>
      {mapArray(items, (item, index) => {
        return (
          <li
            ondragstart={handleStart}
            ondragover={handleDragOver}
            onDrop={handleDrop}
            data-order={index()}
            draggable={true}
          >
            {item}
          </li>
        );
      })}
    </ul>
  );
}

The component logic in your example is not clear enough but mapArray and indexArray does the memoization internally, so you don't have to do it in advance.

You can reorder elements more easily if you store them in a signal and update the order accordingly.

// Swap the elements in place and return a new array
// otherwise signal will not update.
function swapElements(arr: Array<any>, a: number, b: number) {
  let temp = arr[a];
  arr[a] = arr[b];
  arr[b] = temp;
  return [...arr];
};

const initialVal = Array.from({ length: 10 }, ((v, i) => `Item #${i}`));

const App = () => {
  const [items, setItems] = createSignal(initialVal);
  const [prevPos, setPrevPos] = createSignal(0);

  const handleStart = (event: MouseEvent) => {
    setPrevPos(event.target.dataset.order);
  };

  const handleDrop = (event: MouseEvent) => {
    event.preventDefault();
    const nextPos = event.target.dataset.order;
    const arr = swapElements(items(), nextPos, prevPos());
    setItems(arr);
  };

  const handleDragOver = (event: MouseEvent) => {
    event.preventDefault();
  };


  return (
    <ul>
      {mapArray(items, (item, index) => {
        return (
          <li
            ondragstart={handleStart}
            ondragover={handleDragOver}
            onDrop={handleDrop}
            data-order={index()}
            draggable={true}
          >
            {item}
          </li>
        );
      })}
    </ul>
  );
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文