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

折月煮酒 提交于 2019-12-30 03:44:06

问题


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.


回答1:


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




回答2:


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.




回答3:


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 ... } 
}



回答4:


It is also possible to avoid creating a controller, or if there is one already avoid adding more logic in it, by specifying the target property

http://emberjs.jsbin.com/fiwokenoyu/1/edit?html,js,output

in route

js

setupController(controller,model){
  this._super(...arguments);
  controller.set('theRoute', this);
},
actions:{
  openModal(data){
    /*...*/
  }
}

in template

hbs

{{my-component openModalAction=(action 'openModal' target=theRoute)}}



回答5:


Try the Ember add-on called ember-route-action-helper,

https://github.com/dockyard/ember-route-action-helper

You can just replace route-action with action at the time "routable- components" become available.

{{todo-list todos=model addTodo=(route-action "addTodo")}}

So the code above has a similar effect as

Inside the route,

setupController(controller,model){
  this._super(...arguments);
  controller.set('theRoute', this);
},
actions:{
  addTodo(data){
    /*...*/
  }
}

Inside the HBS,

{{todo-list addTodo=(action 'addTodo' target=theRoute)}}


来源:https://stackoverflow.com/questions/31101296/how-to-call-an-action-on-a-route-using-closure-actions

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!