Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to call an action on a route using closure actions?

Tags:

ember.js

I've got openModal action defined on application route. I'm trying to call this action from within a component.

If I use syntax for action bubbling:

{{my-component openModal="openModal"}}

then everything works as expected and I can trigger this action using this.sendAction("openModal").

However, I'm not sure how to get the same result using the new closure syntax:

{{my-component openModal=(action "openModal")}}

In this case, Ember complains that there's no action openModal defined on the controller. Do I have to define this action on every controller that uses my-component? Is there a way to somehow use target option to tell Ember that this action is defined on a route? Is it ok to mix bubbling and closure syntax in a single component?

I'm using Ember 2.0 beta 1.

like image 877
szimek Avatar asked Jun 28 '15 15:06

szimek


3 Answers

Until routable components are introduced somewhere in Ember 2.1 or 2.2 or 2.3 or 2.4 or 2.5 or 2.6 or 2.7, it is impossible to pass a closure action from a route.

For now, you can only pass closure actions from a controller and on to child components.

UPD: Miko Paderes hints that an addon is available: https://github.com/dockyard/ember-route-action-helper

like image 100
Andrey Mikhaylov - lolmaus Avatar answered Nov 09 '22 19:11

Andrey Mikhaylov - lolmaus


Try this:

{{my-component openModal=(action send "openModal")}}

...which makes use of the send method on the controller.

I can't say I fully understand it given that the second argument to send is the context but it is still passing additional arguments to my action in the route correctly. I'm currently using version 2.4.5.

like image 13
Ed . Avatar answered Nov 09 '22 18:11

Ed .


You can send closure actions to the route by proxying them through the controller. This works with any Ember version that supports closure actions. The only caveat is that the action name must differ from controller and route.

For instance, given this template:

{{foo-component myAction=(action 'foo')}}

You would need a foo action on your controller, which could proxy to the route:

proxyFooTo: 'fooBar',
actions: {

  foo(context) {
    this.send('proxyFooTo', context);
  }

}

Then on the route

actions: {
  fooBar(context) {  ... handle fooBar ... } 
}
like image 8
runspired Avatar answered Nov 09 '22 20:11

runspired