Closed patrickdavey closed 7 years ago
You should listen to the end event
and send data to the server only when it fires
Thanks for the quick response! ok I'll do that, probably store up the changes which would otherwise get saved and then persist the lot (or send the entire tree). Thanks very much.
I tried that, and the end
event is only fired if I move components internally within their own list.. if I move it from one list to another it's not getting fired (possibly something broken in the way I'm doing things). The save
is getting called correctly though.
<template>
<draggable element="ul" v-model="children" :options="{group:'people'}" @end="end" :move="move">
<li class="list-group-item" v-for="child in children">
<template v-if="child.nodes">
<part-container :container="child"/>
</template>
<template v-else>
<document-problem :problem="child"/>
</template>
</li>
</draggable>
</template>
<script>
import draggable from 'vuedraggable'
import DocumentProblem from './Document-Problem.vue'
export default {
name: 'part-container',
props: ['container'],
components: { draggable, DocumentProblem },
beforeCreate: function () {
this.$options.components.PartContainer = require('./Part-Container.vue')
},
computed: {
hasChildren: function () {
return this.children.length > 0;
},
children: {
get() {
if( this.container.nodes) {
return this.container.nodes.map((node_id) => this.$store.state.nodes[node_id]);
} else {
return [];
}
},
set(value) {
// value is the new list, but we just want to persist updated ids.
let newOrder = value.filter(function(n) { return n != undefined }).map(function(v) { return v.id } )
console.log("save called")
console.log(newOrder);
console.log(this.container.id);
this.$store.commit('SET_NODES_FOR_CONTAINER', {
containerID: this.container.id,
nodes: newOrder
});
}
}
},
methods: {
move: function(evt) {
console.log(`move: ${this.container.id}`)
},
end: function(evt) {
console.log(`end: ${this.container.id}`)
}
}
}
</script>
<style>
.flip-list-move {
transition: transform 0.5s;
}
.no-move {
transition: transform 0s;
}
.ghost {
opacity: .5;
background: #C8EBFB;
}
.list-group {
min-height: 20px;
}
.list-group-item {
cursor: move;
}
.list-group-item i{
cursor: pointer;
}
</style>
End event is called always. please use the vue debugtools to check that this event is trigerred,
Very interesting. I did use the debug tools, and I can see that the end
event is emitted. What's interesting is that I do not see my little console.log
above being triggered.
I pushed up my toy repo and I'll continue looking into it. The issue I'm having is easy to reproduce, just drag one of the nested elements to an outside it's box, you'll see the end
event is emitted, but that the console.log
isn't triggered.
I'm sure it's something silly I'm doing (I'm very new to vue, and this is frankly the most complex client side functionality I've tried to build!) but still, I can't quite see the issue.
I'm going to try work out how to listen for emitted
events, and see if I can hook in that way.
I think the issue I'm having is that I'm dragging the nested draggables around, the components aren't actually wired up to "know" about the parent-child relationships, so the end
event is being emitted but there's no parent
around to actually listen to the event.
Is there a way to wire in an event bus or similar so that I can catch the events? Anyway, I'll keep on playing!
Ah, my mistake, I had a component wrapping the entire tree structure, once I listened on that for the end
event it all works perfectly.
Thanks again @David-Desmaisons for a fantastic library!!
Hi there,
Thanks so much for this component, massively useful!
I'm trying to use Vue.Draggable to manipulate a nested tree structure. I have used normalizr to normalize my tree, and I can update the components in the store as I drag them around. I made a fiddle here.
My issue is that when moving a component between children, the
set
method is called twice. It totally makes sense that it's called twice, but, as I want to update an API I want to do it as one atomic move. Hopefully some code will make my question clear:My main component has computed methods like this which do the updating:
Now, my plan (possibly a bad plan) is that any time there's a move event I want to persist the move back to an API endpoint. The thing is, I don't really want to send the entire structure back and forth, just a call with the
containerID
and andnodes list
. The issue is I get two of theset(value)
calls, one for the container which had the child moved out of it, and one for where the child got moved into. I want to capture these two events and either do the complete move, or abort.Is there a way to do this with
Vue.Draggable
? Is this a bad approach ?