Components: Sending actions more than one level up


#1

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?


#2

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:


#3

Closure actions + block params solves this. Little example: http://jsbin.com/foheci/edit?html,js,output


#4

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?


#5

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


#6

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?


#7

Sorry, it was just a typo. This version works: http://jsbin.com/kinusewaqe/1/edit?html,js


#8

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.


#9

Ok great. Looking forward to it.


#10

@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: http://jsbin.com/seviyu/edit?html,js,console,output