-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
dom events "leaking" from child view to parent view #2967
Comments
I came up with a simple solution based on the "cid" property of the views (internal unique identifiers - "view1", "view2", etc). Jsfiddle here: https://jsfiddle.net/paulovieira/kmt8kdmy/3/ It consists in this:
Mn.getClosestCid = function(el){
return $(el).closest('[data-cid*="view"]').attr('data-cid');
}; Given a dom element, it will search the dom tree upwards until it finds an element with a "data-cid" attribute that starts with "view", and returns the value. It may sound a bit complex, but steps 1 and 2 could be done by default by marionette, so I only have to make the check in the beginning of the event handler: function(e){
if(Mn.getClosestCid(e.target)!==this.cid){ return; }
...
} Is there any interest in adding this feature to marionette? |
Yeah I'm not sure here. The root of this issue is more of a Backbone specific issue. Any interest in trying out an issue on Backbone? This is great and I think worth pursuing, but it'd be ideal to piggyback off of a Bb solution if at all possible. Thoughts? |
cc: @jridgewell |
@paulovieira Your solution is excellent, thank you so much! I ran into the same problem when I set up a view that has nested sub views of the same type. |
Probably doesn't make sense to include this feature in Mn because seems to be a bit of a particular case. But maybe we should add this case to the documentation? It can be handled with a very simple Mn.Behaviour + a custom utility method like shown above. |
I just implemented it in my specific view because all the nested views are of the same type. However, it does seem like this is an issue that could affect other cases if the events use the same reference. |
this becomes more problematic when regions are nondestructive as re-rendering the parent changes the order of the event handlers and the propogation trick for triggers doesn't work |
When using nested views that have dom events in both the parent and child, it might happen that a dom event triggered in the child view will call also call the event handler in the parent (besides calling the handler in the child, as it should).
This happens if the selectors used in the
events
hash are the same in the parent and in child (or if they are not specific enough). Below is a simple example reproducing the situation (jsfiddle here: https://jsfiddle.net/paulovieira/kmt8kdmy/).If you click the save button in the child view, you see that the handler from the parent is called as well, contrary to my expectation (the child view shouldn't be aware that there is a parent)
This is not a bug. It's simply a consequence of the way backbone uses event delegation in jquery, and the fact that the selectors are the same. There's an informative blog post in the marionette blog about this subject: http://blog.marionettejs.com/2015/02/12/understanding-the-event-hash/index.html
But I was wondering how have been people dealing with this issue. In a situation of deep nested views this might turn out to be problematic. Child views should not care about what is happening above them. If I have to return to some marionette code 1 year later to add a new child view, I shouldn't have to review the details in the parent to make sure the events are not clashing. Do you agree?
Having to add specific dummy classes or ids everywhere ("js-child-view-person", etc) just to avoid these clashes doesn't feel right.
Another option would be to add a top-level container element in the template, so that the selectors in the events hash can start from there. Something like this:
But this also doesn't feel right.
What have been people doing to solve this?
The text was updated successfully, but these errors were encountered: