Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I call a controller action from an Ember route while doing a transition?

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.

like image 717
Josh Padnick Avatar asked Aug 15 '14 20:08

Josh Padnick


People also ask

Can you transition in Ember?

During a route transition, the Ember Router passes a transition object to the various hooks on the routes involved in the transition. Any hook that has access to this transition object has the ability to immediately abort the transition by calling transition.

What is controller in Ember?

What is a Controller? A Controller is routable object which receives a single property from the Route – model – which is the return value of the Route's model() method. The model is passed from the Route to the Controller by default using the setupController() function.

What is route in Ember?

This is the core feature of the Ember. js. The router used for to translate URL into the series of templates and also it represents the state of an application. The Ember. js uses the HashChange event that helps to know change of route; this can be done by implementing HashLocation object.


1 Answers

use controllerFor, http://emberjs.com/api/classes/Ember.Route.html#method_controllerFor

    loading: function(transition, originRoute) {
        var controller = this.controllerFor('foo');
        controller.send('displayLoading');
    }
like image 111
Kingpin2k Avatar answered Oct 24 '22 22:10

Kingpin2k