Sub-component action not bubbling up


#1

I’m trying to send actions from a nested component. The problem is the, the action only get sent from the first level. Here is a jsbin showing the problem. If you expand the tree and click, the action doesn’t make it through all the way up to the parent route.

Any idea how to get it working?


#2

From my understanding, parent Components would need to “send up” the action. They don’t automatically bubble like actions on a Controller to a Route and up the tree that way. Ember 1.9 will alert you when your scenario happens, components that don’t handle a triggered action.

From the Guides:

Instead of sending an action to the template’s controller, then bubbling up the route hierarchy, actions sent from inside a component are sent directly to the component’s Ember.Component instance, and do not bubble.

http://emberjs.com/guides/components/handling-user-interaction-with-actions/


#3

I thought with sendAction I was sending the action up. Otherwise, how is it working for the first level. It seems to me that the problem may be with naming and nesting? I can’t see what the issue is.


#4

I struggled with this for ages too. You have to ‘forward on’ the action until it gets to where you want it. This can be a pain if you have nested components - because each component ends up ‘needing to know’ about a certain action when it might not even need to.


#5

xBlack looks like your js bin works now. I have the same problem but my component uses more the one action so i can’t use the default action name.

When i use named actions they work at the component to component level jsbin example here. But not at the component to controller level jsbin example here.

I think i’m missing something obvious but i cant see it!


#6

I’ve spent half a day digging into this, and eventually found that you can have all actions bubble by aliasing target to targetObject in the outer component.

App.OuterComponent = Em.Component.extend
  target: Em.computed.alias("targetObject")

I can’t decide though if this is a clean way to opt-in to event bubbling, or if it comes too close to implementation details, i.e. might easily break with future updates. Thoughts?


(details of why this works)

A Component’s sendAction is a wrapper around TargetActionSupport’s triggerAction. This does

this.get("targetObject").send(actionName)`

When send (implemented in ActionHandler) gets the action, it will look in the actions hash, or bubble by doing

this.get("target").send(actionName)`

The result: only objects with a target will forward the event. Component’s don’t have a target, so they can’t let the event bubble up. Either they handle it, or it’s gone.


#7

Thank you! Been struggling with this for a while, really unintuitive. Just remember to pass the controller as the target in the handlebars and no need to manually do the alias!


#8

I spent quite a lot of time struggling with this tonight. There is a good answer here on stack overflow that shows you how to deal with this nicely.


#9

If you render component using render() from route, none of this are working, because both this.get('target') and this.get('targetObject') are nulls.

Sample:

this.render('components/lightbox', {
                            outlet: 'modal',
                            view: 'lightBox',
                            into: 'application',
                            controller: this.controllerFor('application')
                        });

this.get('controller') inside component is also null. :(((


#10

Have you tried to bubble the action with the new colsure style? http://emberjs.com/blog/2015/06/12/ember-1-13-0-released.html#toc_closure-actions

Where does it want to bubble the action now? (you should normally see a warning, ‘action blub not implemented in <controller/component/router>’ )