Components: Sending actions more than one level up

I’m trying to use components as much as possible, in order to increase isolation and maintainability, but there’s always some verbosity involved that makes certain things ugly.

For example, let’s say, I have a nested hierarchy of components, and let’s say I want to send an action from the component at the bottom of stack all the way to the top e.g. to a controller. I can obviously do this, by writing “proxy” actions on all mid-level components, but that leads to a lot of boilerplate.

It would be nice if I could do something like:

// in my top-level controller hbs
{{component-one action="handler"}}
// in component-one.hbs
{{component-two action="action"}}
// ...
{{component-one-hundred action="action"}}
// in component-one-hundred.hbs
<button {{action 'onClick'}}>test</button>

// in component-one-hundred.js
actions: {
  onClick: function() {
    this.sendAction();
   }
 }

 // in the controller JS
 actions: {
   handler: function() {
     // do something
   }
 }

I would still wire up the actions at each level, but I would reduce verbosity, by not needing to specify actions on all components in-betweens.

Maybe I’m missing something, but this doesn’t seem to be possible yet. Is something like that planned for Ember 2.0?

4 Likes

What about this (jsbin)?

You can create a component with the action that you want to get to the controller and then extend the rest of the components from it. This way you can save a lot of boilerplate code :slight_smile:

Closure actions + block params solves this. Little example: JS Bin - Collaborative JavaScript Debugging

5 Likes

thanks. in case the code in question is completely inside the innermost component template file, I guess I would have to pass the target around as an argument?

I am not understanding. Can you update my fiddle to reflect what you mean?

In your example, you are dynamically wiring the components together by passing in blocks to the components. I want the nesting to be static. Like so:

But this doesn’t do what I want. Would I need to pass the target object around?

Sorry, it was just a typo. This version works: JS Bin - Collaborative JavaScript Debugging

What you have seems correct. Maybe in the future we’ll get to use something like spread to thread arguments through … kind of like JSX use of {...props} so you don’t have to explicitly thread through arguments.

Ok great. Looking forward to it.

@Fryle @jasonmit Thanks both of you, I was exactly looking for an example of the best practice a this time. Seems like this one is the good one :smile:

Also, the currying capabilities give even more flexibilty: JS Bin - Collaborative JavaScript Debugging