Reputation: 4784
Assuming I have a route with an event like
App.FooRoute = Ember.Route.extend({
events: {
anAction: function(){
}
}
})
How do I trigger it from the view of another route/controller ?
<a {{action anAction target='???'}}> a link </a>
Upvotes: 3
Views: 767
Reputation: 2201
As explained in the Ember Docs, you can use a built in mixin called Ember.ViewTargetActionSupport to send actions to a different controller or view or route within your app.
A simple way to handle your problem is as follows:
The current template:
<a {{action 'actionInView' target='view'}}>Click me</a>
The View:
App.CurrentView = Em.View.extend(Em.ViewTargetActionSupport, { // Note the mixin
actions: { // Actions hash
actionInView: {
this.triggerAction({ // Without a target this will bubble through the routes
action: 'theActionToCall', // Name of the action you *actually* want to call
target: App.TargetController, // Or whatever the name of your target is
});
},
},
});
The Target Controller:
App.TargetController = Em.ObjectController.extend({
actions: {
theActionToCall: {
// This is where you do the action stuff that you *actually* are trying to do
},
},
});
Essentially, the action called actionInView does nothing but call the action you actually want but can't access because it's in a different part of your application. I you don't specify a target then you can place the action on a parent route, or the application route, and it will get called.
Upvotes: 0
Reputation: 65242
Let's say you have routes like this:
App.Router
|
+ FooRoute
|
+ BarRoute
What would it mean to send an action from the FooRoute
to the BarRoute
? The user has gone to /foo
, so the FooModel
, FooController
, and FooView
have been initialized, but the Bar*
ones haven't. What would the action do?
In this case, having a BarModel
around is a prerequisite for the FooRoute
. The most Ember-like way to solve this is to use nested routes:
App.Router.map(function() {
this.resource('bar', function() {
this.route('foo');
}
});
The user goes to /bars/123/foo
and click on the link, triggering anAction
. Ember will automatically bubble that action up the route hierarchy, so you can simply define anAction
on BarRoute
.
In this case, having a BarModel
is unnecessary. anAction
does some stuff that isn't really Foo
-related, but nor is it Bar
-related. We can use the same bubbling trick, but instead of defining anAction
on BarRoute
, we define it on the main router.
Let's say that the action needs the "current user." This case is much like #2 in that you don't need to nest routes. It does, however require you to have a globally-addressable controller like App.currentUserController
. You can directly specify this as the target
of the {{action}}
.
If none of the above options seem quite right, you can use controllerFor
to set a barController
property on the fooController
:
App.FooRoute = Ember.Route.extend({
setupController: function(controller) {
var barController = this.controllerFor('bar');
controller.set('barController', barController);
}
});
Then you can do {{action anAction target=barController}}
.
Ember will automatically try the action against the controller, then bubble up the route hierarchy. If models depend on other models, you may need nested routes or global controllers to ensure that your prerequisites are hooked up.
Upvotes: 2