1

I have been banging my head against this for 2 days solid now and I need some advice on how to track down the root of this problem. Hopefully someone (you, reading this perhaps?) has had a problem similar enough that you can offer some help.

My app has a few things draggable via the jQuery UI widget with that name. This works really well until I navigate inside the app using Ember's routing. Something happens when the UI is refreshed and the things in and around the draggable items are re-generated.

So, what happens?

After a routing redraw of the UI, the draggable divs most significantly do not update their position when the mouse pointer is over the image element that they are supposed to be dragged around on top of. The motion is also jerky which looks like it is due to the position not updating until the pointer is outside of the draggable div. Also the dragging gets stuck and the div continues to follow the mouse after the mouse-button is released.

Update

I have been adding breakpoints to jQueryUI Mouse, the mouse event handler that draggable relies on. Breaking when it detects a mouse down and mouse up event I see that there is no up event registered when I drag. In fact, clicking anywhere in the div re-rendered after routing does not register either down or up events.

I just have no idea what I can be doing to mess up the mouse listeners.

Update 2

I have kept going down the mouse event rabbit hole and come up with the following. There is a closed issue on Ember.js related to events not bubbling up to the document for jQuery UI Mouse to catch it. So I put in some log lines in at the location mentioned to see what was going on. I only log on mouseDOwn events to avoid flooding the console.

What I see is that before an in-Ember routed navigation the entire Ember hierarchy returns an undefined manager for the event. After routing though, one of the views return null which immediately halts the bubbling. Not even the ApplicationView at the root of the Ember app gets to have a say, let alone jQuery UI on the document node.

The reason is returns null is odd, though. It is because the view it is checking is not in the list of views Ember keeps internally. It is clearly there in the DOM but has somehow not been registered or been unregistered at some point.

The hunt continues...

And what have I done about it?

I made jQuery draggable a mixing instead of calling it "manually"

I followed this SO question and the associated code on github to make jQuery UI create and destroy observers in a more integrated fashion. Works exactly the same as before this re-factoring though.

I unloaded and disabled all other javascript libraries used by the app

I had some canvas drawing stuff in there which I removed for testing.

I removed as much of the UI hierarchy as I could

I put the ember app directly under the body and also made the app view "tag-less" to change and reduce the depth at which the buggy draggable stuff happens. I even short-circuited one whole view level connecting directly to the app view's outlet and not to a sub-view's outlet.

I made parts of the navigation draggable

I made a few nav items, that do not refresh when routing, draggable... they continue to drag as they should after routing around.

I made things draggable in another Ember app

This problem does not occur in another Ember app inside the same Rails project (same css and base html, javascript). I made some random buttons and things in that app draggable and "routed" around like crazy and they always continued to be draggable as they should. Something specific to the structure or UI hierarchy looks to be causing it.

Of-course, I also logged numerous callbacks and switched browsers

To ensure that things were being torn down correctly when the appropriate UI elements are removed I have been logging a ridiculous number of things tracing each log line to ensure it looks like the right things happen. The same occurs in the latest Safari, Chrome and Firefox.

Why blame Ember and Draggable?

I had this application in prototype form as a TangledMessOfJavascriptâ„¢ application. It did all the same things. Replacing parts of the DOM as navigation, using Draggable and the same basic UI hierarchy (except for some Ember-encouraged stuff).

How about a JS fiddle?

Even though I am asking for advice I really like to not try to generate a fiddle from this non-trivial app hierarchy. I am not trying to be lazy. It would seriously take me a full day to make a fiddle of this partly because it is an at-work-app which contains some things I don't think I can share, but mostly just because it is not a trivial cornered-off problem I can just make a simple test case.

What do I want?

I am not looking for someone to magically sole this... What I would love to get is some suggestions on how the heck I track this down. I am leaning towards some rouge event listener or some other oddity. I have not found a good way to debug this kind of thing.

Community
  • 1
  • 1
Martin Westin
  • 1,419
  • 1
  • 14
  • 25

1 Answers1

2

Guided by this closed issue on Ember.js, I managed to find out that the problem is using Views with static elementId in outlets. When transitioning between routes Ember registers the next view instance before un-registering the old one from Ember's global views hash. SInce both views have the same ID, used as the key in the hash, this will cause the view to be missing from this hash. This in turn will cause any event bubbling to halt silently. In my case, any mouse clicks inside this view would be swallowed by the EventManager and not bubble up the hierarchy.

I created an issue on github to find out if this is a but or a known limitation. https://github.com/emberjs/ember.js/issues/1553

Martin Westin
  • 1,419
  • 1
  • 14
  • 25