【问题标题】:How do I call a controller action from an Ember route while doing a transition?如何在进行转换时从 Ember 路由调用控制器操作?
【发布时间】:2014-10-09 14:53:51
【问题描述】:

我的目标是在 Ember 通过 Ember 路由获取模型数据时在我的页面上显示一个精美的“正在加载...”图形。

这让我找到了http://emberjs.com/guides/routing/loading-and-error-substates/。这启发了我在我的页面控制器上创建一个动作,该动作将在 DOM 中显示“加载”覆盖窗口。例如,这是我的控制器:

controllers/users.js:

export default Ember.ArrayController.extend({
    ...
    actions: {
        displayLoading: function() {
            // Show the DOM element that says "Loading..."
        },
        ...
    }
});

我想在我的数据加载时调用它,所以我定义一个路由如下:

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');
        }
    }
});

但是当我这样做时,我得到了这个错误:

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.

所以我的问题是我在哪里可以定义这个动作,以便我的loading 方法能够调用它?

请注意,尝试this.send('displayLoading') 给了我这个错误:

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

更新:我能够在路由本身上捕捉到这个动作,但是我仍然无法在我的控制器上调用这个动作。

更新#2:感谢@kingpin2k 的回答,我已经解决了这个问题。对于那些感兴趣的人,这里有一个完整的解决方案:

controllers/users.js:

export default Ember.ArrayController.extend( {
    actions: {
        showLoading: function() {
            this.set('isLoading', true);
        },

        hideLoading: function() {
            this.set('isLoading', false);
        },
    }
});

路由器/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');
        }
    }

});

一个关键的见解是我可以在我的控制器上设置一个isLoading 属性,该属性确定我的模态“正在加载...”窗口是否显示在 Handlebars 模板中。

【问题讨论】:

    标签: javascript ember.js


    【解决方案1】:

    使用controllerForhttp://emberjs.com/api/classes/Ember.Route.html#method_controllerFor

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

    【讨论】:

    • 是的,就是这样!我可以发誓我尝试过this.controllerFor('foo'),但是当我再次尝试它时它起作用了。我会接受你的回答,并发布一些关于我如何完整设置的详细信息。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2013-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多