ember-drag-drop
ember-drag-drop copied to clipboard
drag-handle is not reconnected when component nested under draggable-object re-renders
When rendering a dynamic list of components such as:
{{#each items as |item|}}
{{#draggable-object content=item dragHandle='.some-drag-handle'}}
{{component item.componentImplName item=item}}
{{/draggable-object}}
{{/item}}
For the initial render, everything works perfectly.
When the dynamic component re-renders because componentImplName
changes, the HTML element with .some-drag-handle
on it is not detected.
I haven't looked at code for ember-drag-drop, but I assume there's some code that runs on initial render after child component renders that isn't re-executed when the child is removed and re-rendered.
A workaround is to completely re-render all items in the list (but that would be an unnecessary distraction for the end-user).
Let me know if you would like me to debug more. I also wouldn't mind trying to fix the issue upstream but I might need some guidance for that.
The code in question is here: https://github.com/mharris717/ember-drag-drop/blob/master/addon/components/draggable-object.js#L40-L52
We would need to have an API to trigger disconnecting and re-connecting when a child component re-renders.
Once easy to imagine API is to {{yield draggableApi}}
in draggable-object
where draggableApi
exposes a method called updateDragHandle()
. When invoked (by the child component), the routine to setup the event listeners on the drag handle would be re-run.
Thoughts on this approach? I plan to monkey-patch this idea in our application soon and I'll report back how well it works.
The API design is lightly inspired by what I've seen in addons like ember-basic-dropdown and ember-power-select.
This actually seems more like just a bug to me. A re-render of the child component should not affect this. If you have a reproduction that would be helpful, but I think I can use one of the demos to reproduce that. It should be able to be handled using component lifecycle functions like componentDidUpdate.
This actually seems more like just a bug to me. A re-render of the child component should not affect this. If you have a reproduction that would be helpful, but I think I can use one of the demos to reproduce that. It should be able to be handled using component lifecycle functions like componentDidUpdate.
When the component in question re-renders, the entire DOM of the component is torn down, so the element containing the dragHandle
selector no longer has mouse events attached to it.
We might be able to reproduce the issue in an ember-twiddle, too (if it lets you use addons).
Yeah it makes sense, just not sure the best way to fix it, probably using contextual components.
Could have observer on content
property and reattach whenever that changes. But that would still be a problem when content
is the same (e.g., an ember-data model) and changing a model property causes the drag-handle to re-render.
@les @dgavey
One observation I noticed: If you tap the handle first then touch/drag the handle.. it will work..
i.e. the draggable-object becomes draggable="true"
then the drag events will fire when you move it around.
That indicates to me that the event listeners are still bound.. in some way at least.
I'm investigating code now to see if there is anything i can find