最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How do I call a controller action from an Ember route while doing a transition? - Stack Overflow

programmeradmin0浏览0评论

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.

Share Improve this question edited Aug 15, 2014 at 21:47 Josh Padnick asked Aug 15, 2014 at 20:27 Josh PadnickJosh Padnick 3,2681 gold badge27 silver badges34 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 16

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

    loading: function(transition, originRoute) {
        var controller = this.controllerFor('foo');
        controller.send('displayLoading');
    }
发布评论

评论列表(0)

  1. 暂无评论