Reputation: 85
I am using cytoscapejs and the extension compound-drag-and-drop. My aim is to shoot an event to my database when I drag a node and drop it over another. I am taking the id (of my future child node) with cdndtapstart or cdndout (when it is inside a compound node) and event.target._private.data.id, and then, with cdnddrop I call dropSibling._private.data.id, and with this data I can do my ajax call. The problem that I have is that those events are acumulating one over another, if I drag the node once is fine, the second time that I drag it, it will produce two ajax call, the third time will give me three calls. Is there a way to avoid this or should it be reported as a bug?
cy.on('cdndout', 'node', function(event, dropTarget, dropSibling){
let type = event.target._private.data.type;
let id = event.target._private.data.id;
let gId = event.target._private.data;
if(type == 'device'){
cy.on('cdnddrop', function(event, dropTarget, dropSibling){
var typeDe = dropSibling._private.data
if(typeDe == undefined){
$.notify({message: err},{type: 'danger'});
createGraph()
} else {
let uuid = event.target._private.data.id;
let gId = dropSibling._private.data.id;
setResourceToGroup(uuid, gId, cb)
.then(reso => getAllResources())
.then(allReso => createGraph())
.catch(err => {
$.notify({message: parseLog(err)},{type: 'danger'});
createGraph()
})
}
})
}
})
So with this code, the ajax call that I have in the function setResourceToGroup, will be executed as many times as I drag the node. I am guessing I am not handling the events properly and they are accumulating... any help with that?
Upvotes: 1
Views: 330
Reputation: 6074
Events in cytoscape.js are quite simple, you bind an event and that event fires when the conditions of the binded event are met. The problems start, when you call the same binding operation twice or more. Then your event works normally, but the second you call that bind again, you have 2 events on your hand. And they will fire both at the same time! So how do you solve that?
Every time you call cy.bind() (cy.bind() is the same as cy.on()), you have to evaluate if that line can be executet more than once. If yes, then you have to do this:
cy.unbind('cdnout');
cy.bind('cdndout', 'node', function(event, dropTarget, dropSibling){
let type = event.target._private.data.type;
let id = event.target._private.data.id;
let gId = event.target._private.data;
if(type == 'device'){
cy.unbind('cdnddrop);
cy.bind('cdnddrop', function(event, dropTarget, dropSibling){
var typeDe = dropSibling._private.data
if(typeDe == undefined){
$.notify({message: err},{type: 'danger'});
createGraph()
} else {
let uuid = event.target._private.data.id;
let gId = dropSibling._private.data.id;
setResourceToGroup(uuid, gId, cb)
.then(reso => getAllResources())
.then(allReso => createGraph())
.catch(err => {
$.notify({message: parseLog(err)},{type: 'danger'});
createGraph()
});
}
});
}
});
By unbinding the event first, you can only have one event firing at once :)
Upvotes: 1