I am using Dragula to create a set of drag and drop components in Ember. I pass a list of items through to a parent wrapper that contains multiple droppable buckets. This list of items is filtered initially so that they correct items are rendered in the correct bucket. Then Dragula is wired up so items can be dragged and dropped. When a drop event occurs, I try to update the underlying Ember object. This can cause the filter to be re-applied and some rendering to occur. The problem is the DOM has been manipulated by Dragula and is not the same as Ember thinks it should be and DOM nodes just disappear.
How can I get Ember and Dragula to play nice when they both think they own the DOM and its current representation? I've tried cancelling the draggle drop event and then letting Ember set values with limited success.
dnd-wrapper/template.hbs
{{yield (action "register")}}
dnd-wrapper/component.js
export default Ember.Component.extend({
drake: null,
buckets: [],
items: [],
initDragula: Ember.on('willInsertElement', function() {
this.set('drake', window.dragula());
}),
setupDragulaEvents: Ember.on('didInsertElement', function() {
this.get('drake').on('drop', (itemEl, destinationEl, sourceEl) => {
let dest = this.buckets.findBy('element', destinationEl);
let source = this.buckets.findBy('element', sourceEl);
let item = this.items.findBy('element', itemEl);
item.component.set('item.bucket', dest.component.get('value'));
});
}),
actions: {
register(type, obj) {
if(type === 'bucket') {
this.get('drake').containers.push(obj.element);
this.buckets.pushObject(obj);
}
else {
this.items.pushObject(obj);
}
}
}
});
dnd-bucket/template.hbs
<h2>bucket {{value}}</h2>
<ul>
{{#each filteredItems as |item|}}
{{dnd-item item=item register=register}}
{{/each}}
</ul>
dnd-bucket/component.js
export default Ember.Component.extend({
items: null,
registerWithWrapper: Ember.on('didInsertElement', function() {
this.register('bucket', {
component: this,
element: this.$('ul')[0]
});
}),
filteredItems: Ember.computed('items.@each.bucket', function() {
return this.get('items').filterBy('bucket', this.get('value'));
})
});
dnd-item/template.hbs
{{item.title}}
dnd-item/component.js
export default Ember.Component.extend({
registerWithWrapper: Ember.on('didInsertElement', function() {
this.register('item', {
component: this,
element: this.$()[0]
});
})
});
Online Demo: http://ember-twiddle.com/c086d2853a926c310a23
GitHub Demo: https://github.com/RyanHirsch/dragula-ember-example