Javascript 在Ember.js中呈现应用程序之前,等待加载模型

Javascript 在Ember.js中呈现应用程序之前,等待加载模型,javascript,ember.js,ember-data,Javascript,Ember.js,Ember Data,我有许多不同的应用程序级模型,例如,当前用户、当前帐户等,我希望在呈现应用程序之前加载这些模型。应该如何以及在何处这样做?帮助很大,但它没有涵盖异步方面 下面的代码实现了我想要的,但是在beforeModel中加载模型(利用它等待承诺解决)似乎不正确。我是否应该在ApplicationRoute中加载这些模型 App.ApplicationController = Ember.Controller.extend({ currentAccount: null }); App.Applicat

我有许多不同的应用程序级模型,例如,当前用户、当前帐户等,我希望在呈现应用程序之前加载这些模型。应该如何以及在何处这样做?帮助很大,但它没有涵盖异步方面

下面的代码实现了我想要的,但是在
beforeModel
中加载模型(利用它等待承诺解决)似乎不正确。我是否应该在
ApplicationRoute
中加载这些模型

App.ApplicationController = Ember.Controller.extend({
  currentAccount: null
});

App.ApplicationRoute = Ember.Route.extend({
  beforeModel: function () {
    var self = this;

    return App.Account.find(...).then(function (account) {
      self.controllerFor('application').set('currentAccount', account);
    });
  }
});

谢谢你的帮助

诀窍是从路由的模型方法返回承诺。
这将导致路由器转换为App.LoadingRoute路由,直到promise解决(可用于加载指示条/轮子等)
当承诺解决时,App.LoadingRoute将被停用,并将调用原始路由的setupController方法。
这适用于余烬数据承诺、JQuery的$.ajax承诺和余烬模型的获取承诺。
只需确保在解决承诺后返回实际模型。
如果承诺被拒绝,这也是一个处理错误的好地方——但我将把这留给其他一些问题

至于您应该在哪里加载模型,这取决于您的应用程序的使用情况。
通常,您会加载一个模型,其中URL表示您需要该模型-经验法则是在URL中指示模型ID。
如果需要预取一些数据,这当然会发生变化

下面是一些代码:

App.SomeRoute = Ember.Route.extend({
   model: function(params){
       return App.SomeModel.fetch(params.model_id).then(function(modelData){
           // it is better to return the actual model here, and not the promise itself
           return App.SomeModel.find(params.model_id);
       });

   },
   setupController: function(controller, model){
       controller.set("model", model);
       // do some controller setup here - can be omitted if no setup is needed
       // this will run only after the promise has been resolved.
   }
});

App.LoadingRoute = Ember.Route.extend({
        activate: function(){
            this._super();
            // add some loading indication here
        },
        deactivate: function(){
            this._super();
            // remove loading indication
        }
}

希望这能有所帮助。

我通过在ApplicationRoute中使用嵌套承诺和afterModel方法成功地完成了这项工作

App.ApplicationRoute = Ember.Route.extend({

    model: function() {

        // load the reservation (a globally needed model)
        return App.Reservation.fetch().then(function(reservations) {
            return reservations.get('firstObject');
        });

    },

    afterModel: function() {

        // Load all other globally needed models
        var self = this;
        return App.Gender.fetch().then(function(genders) {
            self.controllerFor('application').set('genders', genders);
            return App.FilterAttribute.fetch().then(function(filterAttributes) {
                self.controllerFor('application').set('filterAttributes', filterAttributes);
                //return App.SomeOtherModel...
            });
        });

    },

    setupController: function(controller, model) {
        controller.set('reservation', model);
    }

});
工作非常完美:-)在加载所有记录之前,应用程序保持在加载路径中。
请注意,我正在使用,但这应该没有什么区别,它只需要返回一个承诺。

您想预加载数据/模型来初始化您的应用程序,并且感觉beforeModel不正确吗

听起来你需要一个应用程序初始化器

在这种情况下,您的朋友:

App.deferready()//暂停应用程序的进程,直到此调用的所有实例(即:多个初始值设定项)与以下调用的实例匹配:

App.advanceReadiness() / /认为这相当于一个允诺解析调用。

1) 通过直接查找用户,修改提及的位置以适应应用程序设置:

Ember.Application.initializer({
    name: 'loadUser',
    after: 'store',
    initialize: function(container, app) {
        // modify this following to suit how you're determining the account
        var url = 'user/' + currentAccount;
        // tell the app to pause loading until advanceReadiness is declared
        app.deferReadiness();

        // load from JSON 
        Ember.$.getJSON('url').then(function(json) {

            var store = container.lookup('store:main');
            store.load(app.User, json);

            // tell app to start progressing again
            app.advanceReadiness();
        });
    }
});
2) 通过元标记:

Ember.Application.initializer({
    name: 'currentUser'
    after: 'store',

    initialize: function(container, app) {
        app.deferReadiness();

        $(function() {
            // Look up an attribute in a meta tag
            var store      = container.lookup('store:main'),
                attributes = $('meta[name="current-user"]').attr('content');

            if (attributes) {
                var obj        = store.load(app.User, JSON.parse(attributes)),
                    user       = App.User.find(obj.id),
                    controller = container.lookup('controller:currentUser').set('content', user);

                container.typeInjection('controller', 'currentUser', 'controller:currentUser');
            }
            app.advanceReadiness();
        });
    }
});
3) 通过会话数据:

Ember.Application.initializer({
    name  : 'currentUser',
    after : 'session',
    initialize: function(container, app) {
        var controller = container.lookup('controller:currentUser');
        container.typeInjection('controller', 'currentUser', 'controller:currentUser');
    }
});

谢谢,但您并没有真正回答我应该在哪里加载我在任何地方都需要的应用程序级模型。换句话说,不依赖URL的模型。如果您预先需要它们,可以使用Ember.Application的init方法。我似乎找不到任何迹象表明它正在等待承诺解决。你能详细解释一下吗?谢谢。当您从路由的model方法返回承诺时,路由器将临时转换为LoadingRoute(您应该使用旋转的加载轮或类似的东西定义一个漂亮的加载路由),直到承诺得到解决。当承诺得到解决时,它将返回到您的路线并按预期运行setupController。您可以在这里找到一个示例:和一些参考: