Nested draggable components
See original GitHub issueHey there, awesome lib, thank you!
I’m having some trouble implementing a hierarchy of draggable components…
Data scheme of <Tour> component:
[
{
id: 1
title: 'nomination #1',
travelers: [
{id:1, name: 'foo'}
],
rooms: [
{
id: 1,
title: 'room #1',
travelers: [
{id:2, name:'bar'},
{id:3, name:'baz'},
],
},
{
id: 3,
title: 'room #3',
travelers: [],
}
]
},
{
id: 2
title: 'nomination #2',
travelers: [
{id:4, name: 'bax'}
],
rooms: [
{
id: 2,
title: 'room #2',
travelers: [
{id:5, name:'bop'},
{id:6, name:'blop'},
],
}
]
}
]
Component layout:
<Tour>
- <Nomination>
- <Traveler>
- <Traveler>
- <Room>
- <Traveler>
- <Traveler>
- <Nomination>
- <Room>
The logic behind is that each tour can have nominated accommodations, each nomination can have travelers without an assigned room and a list of rooms, each of which can have assigned travelers.
The nomination component receives its data via v-model, and is watched and mirrored to an inner variable when changed. This variable is used when constructing v-dragula. If the inner value changes, it emits it with the input name.
This is working so far, drag&drop events manipulate the root data structure, yay! (it is awesome, took me like 30 mins to implement)
Now to my real problem, events get fired twice:
tour.vue:354 travelers:drop {el: div.tour-traveler.gu-transit, container: div.tour-nomination-travelers.sort-target.pull-left, source: div.tour-room-travelers, name: "travelers", service: {…}, …}
tour.vue:354 travelers:drop {el: div.tour-traveler.gu-transit, container: div.tour-nomination-travelers.sort-target.pull-left, source: div.tour-room-travelers, name: "travelers", service: {…}, …}
tour.vue:344 travelers:insertAt {elements: {…}, targetModel: ModelManager, transitModel: {…}, dragIndex: 0, dropIndex: 2, …}dragIndex: 0dropIndex: 2elements: {drop: div.tour-traveler, target: div.tour-nomination-travelers.sort-target.pull-left, source: div.tour-room-travelers}indexes: {source: 0, target: 2}models: {source: ModelManager, target: ModelManager, transit: {…}}name: "travelers"sourceModel: ModelManager {opts: {…}, name: "travelers", drake: {…}, modelRef: Array(0), model: Array(0), …}targetModel: ModelManager {opts: {…}, name: "travelers", drake: {…}, modelRef: Array(2), model: Array(2), …}transitModel: {…}__proto__: Object
tour.vue:344 travelers:insertAt {elements: {…}, targetModel: ModelManager, transitModel: {…}, dragIndex: 0, dropIndex: 2, …}dragIndex: 0dropIndex: 2elements: {drop: div.tour-traveler, target: div.tour-nomination-travelers.sort-target.pull-left, source: div.tour-room-travelers}indexes: {source: 0, target: 2}models: {source: ModelManager, target: ModelManager, transit: {…}}name: "travelers"sourceModel: ModelManager {opts: {…}, name: "travelers", drake: {…}, modelRef: Array(0), model: Array(0), …}targetModel: ModelManager {opts: {…}, name: "travelers", drake: {…}, modelRef: Array(2), model: Array(2), …}transitModel: {…}__proto__: Object
tour.vue:347 travelers:dropModel {target: div.tour-nomination-travelers.sort-target.pull-left, source: div.tour-room-travelers, el: div.tour-traveler.gu-transit, dragIndex: 0, dropIndex: 2, …}
tour.vue:347 travelers:dropModel {target: div.tour-nomination-travelers.sort-target.pull-left, source: div.tour-room-travelers, el: div.tour-traveler.gu-transit, dragIndex: 0, dropIndex: 2, …}
Any help/advice is appreciated!
Issue Analytics
- State:
- Created 6 years ago
- Comments:5 (3 by maintainers)
Top GitHub Comments
Great to hear! I just made some vast improvements to the docs and made note of some typical gotchas that trip some developers… Should be easier now.
Hi @lajosbencz,
Thanks. I’m glad you like it 😃
I haven’t played with this library/plugin/component for a while. I’m hardly a Vue expert myself. I used this project to get some insight into Vue internals and plugin development, but I might have made a few mistakes on the infrastructure…
I would advise you to clone the master and
npm link
it in your own project, then debug from there. Could well be an error related to Vue reactivity with Arrays (see Vue 2 vs Vue 3 reactivity. I didn’t quite grasp reactivity enough at the time I developed this plugin. Found it very hard to find good documentation. So perhaps try usingVue.set
explicitly when modifying arrays, as described in this blog post.I think I tried various “hacks” to make array changes trigger reactivity and view update. Due to Vue updates (improvements) since then, it might trigger “double time” now?
Best bet would be to subclass the
ModelManager
and theActionManager
. Try debugging thedo
anddoAct
methods etc. ofActionManager
to see what the problem is…I guess you can always keep a reference to last emit (or do action) and ignore any msg if it is the same as the last one received
Cheers!