My objective is to display a fancy "loading..." graphic on my page while Ember fetches model data through the Ember route.
This led me to /. That inspired me to create an action on my page's controller which would show the "loading" overlay window in the DOM. For example, here's my controller:
controllers/users.js:
export default Ember.ArrayController.extend({
...
actions: {
displayLoading: function() {
// Show the DOM element that says "Loading..."
},
...
}
});
I'd like to call that while my data is loading, so I then define a route as follows:
routes/users.js:
export default Ember.Route.extend({
model: function( params ) {
return this.store.find('user', params );
},
actions: {
loading: function(transition, originRoute) {
transition.send('displayLoading');
}
}
});
But when I do this, I get this error:
Uncaught Error: Nothing handled the action 'displayLoading'. If you did handle the action, this error can be caused by returning true from an action handler in a controller, causing the action to bubble.
So my question is where can I define this action so that my loading
method will be able to call it?
Note that trying this.send('displayLoading')
gave me this error:
Can't trigger action 'displayLoading' because your app hasn't finished transitioning into its first route. To trigger an action on destination routes during a transition, you can call .send() on the Transition object passed to the model/beforeModel/afterModel hooks.
.
Update: I am able to catch this action on the route itself, but then I still can't call the action on my controller.
Update #2: Thanks to @kingpin2k's answer, I've resolved this. For those interested, here is a full solution:
controllers/users.js:
export default Ember.ArrayController.extend( {
actions: {
showLoading: function() {
this.set('isLoading', true);
},
hideLoading: function() {
this.set('isLoading', false);
},
}
});
routers/users.js:
export default Ember.Route.extend({
model: function( params ) {
return this.store.find('user', params );
},
actions: {
loading: function() {
this.controllerFor('users').send('showLoading');
},
didTransition: function() {
this.controllerFor('users').send('hideLoading');
}
}
});
A key insight was that I can set an isLoading
property on my controller which determines whether my modal "Loading..." window is showing in the Handlebars template.
My objective is to display a fancy "loading..." graphic on my page while Ember fetches model data through the Ember route.
This led me to http://emberjs.com/guides/routing/loading-and-error-substates/. That inspired me to create an action on my page's controller which would show the "loading" overlay window in the DOM. For example, here's my controller:
controllers/users.js:
export default Ember.ArrayController.extend({
...
actions: {
displayLoading: function() {
// Show the DOM element that says "Loading..."
},
...
}
});
I'd like to call that while my data is loading, so I then define a route as follows:
routes/users.js:
export default Ember.Route.extend({
model: function( params ) {
return this.store.find('user', params );
},
actions: {
loading: function(transition, originRoute) {
transition.send('displayLoading');
}
}
});
But when I do this, I get this error:
Uncaught Error: Nothing handled the action 'displayLoading'. If you did handle the action, this error can be caused by returning true from an action handler in a controller, causing the action to bubble.
So my question is where can I define this action so that my loading
method will be able to call it?
Note that trying this.send('displayLoading')
gave me this error:
Can't trigger action 'displayLoading' because your app hasn't finished transitioning into its first route. To trigger an action on destination routes during a transition, you can call .send() on the Transition object passed to the model/beforeModel/afterModel hooks.
.
Update: I am able to catch this action on the route itself, but then I still can't call the action on my controller.
Update #2: Thanks to @kingpin2k's answer, I've resolved this. For those interested, here is a full solution:
controllers/users.js:
export default Ember.ArrayController.extend( {
actions: {
showLoading: function() {
this.set('isLoading', true);
},
hideLoading: function() {
this.set('isLoading', false);
},
}
});
routers/users.js:
export default Ember.Route.extend({
model: function( params ) {
return this.store.find('user', params );
},
actions: {
loading: function() {
this.controllerFor('users').send('showLoading');
},
didTransition: function() {
this.controllerFor('users').send('hideLoading');
}
}
});
A key insight was that I can set an isLoading
property on my controller which determines whether my modal "Loading..." window is showing in the Handlebars template.
1 Answer
Reset to default 16use controllerFor
, http://emberjs.com/api/classes/Ember.Route.html#method_controllerFor
loading: function(transition, originRoute) {
var controller = this.controllerFor('foo');
controller.send('displayLoading');
}