Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incorrect dom list with reactive array after drag #57

Open
gyhyfj opened this issue Dec 29, 2022 · 2 comments
Open

Incorrect dom list with reactive array after drag #57

gyhyfj opened this issue Dec 29, 2022 · 2 comments

Comments

@gyhyfj
Copy link

gyhyfj commented Dec 29, 2022

My code is like this:

<template>
  <Sortable :list="list" item-key="id" :options="options">
    <template #item="{ element }">
      <div class="draggable" :key="element.id">
        {{ element.name }}{{ element.id }}
      </div>
    </template>
  </Sortable>
</template>

<script setup lang="ts">
import { reactive } from "vue"
import { Sortable } from "sortablejs-vue3"

const list = reactive([
  {
    id: "111",
    name: "item1",
  },
  {
    id: "222",
    name: "item2",
  },
])

const options = {
  draggable: ".draggable",
  animation: 150,
  ghostClass: "ghost",
  dragClass: "drag",
  scroll: true,
  forceFallback: true,
  scrollSensitivity: 50,
  scrollSpeed: 10,
  bubbleScroll: true,
}
</script>

If I drag them, then modify list by splicepush or other methods, the dom list will be incorrect , some item could repeat, even if they have the same id.

For example, if I drag one of the item , and then remove every item in this reactive list, the dom dragged will still stay there. Then I push new item into the list, that Dom will still remain there even if it have the same id with new item

@WaiChungK
Copy link

WaiChungK commented Jan 11, 2023

I was facing this issue as well and one workaround way that you can try is that u can put key on the Sortable component based on ur reactive data values that will be changed.

There could be other better ways you could do this such as md5 hashing, but this is just a rough idea.

Again, i don't think this is quite right but it is a workaround to solve the issue.

Crude example:

<Sortable :list="list" item-key="id" :options="options" :key="JSON.stringify(list)">
  <template #item="{ element }">
	  <div class="draggable" :key="element.id">{{ element.name }}{{ element.id }}</div>
  </template>
</Sortable>

Senryoku added a commit to Senryoku/Draftmancer that referenced this issue Mar 31, 2023
When moving object within a list via drag & drop, sortable will not automatically update the
underlying array. This patch adds `update` events to actually keep the underlying lists in sync
with the DOM elements changes. This fixes lots of weird behaviors in CardPool.

There's also what seems to be a reactivity bug with SortableJS-vue3 (see
MaxLeiter/sortablejs-vue3#57): The component was not always
correctly re-rendered when externally modified (for example, with multiple cards in the collapsed
sideboard, drag one card to the end of the sideboard then click on it to move it to the deck:
the card was correctly moved, but the SortableJS-vue3 component was not correctly updated resulting
in a ghost card staying at the bottom of the sideboard and leading to many errors.)
This patch also adds dynamic keys to all SortableJS-vue3 components to force re-renders when the length
of the list externally changes. This may not be enough in all cases (when swapping cards without changing
the length for example), but it's enough for now, and way simpler than computing a md5 or any
other unique identifier.
@lilkimo
Copy link

lilkimo commented Jan 21, 2024

Same issue here (1.2.11), Is this a bug?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants