【问题标题】:How to load belongsTo/hasMany relationships in route with EmberJS如何使用 EmberJS 在路由中加载 belongsTo/hasMany 关系
【发布时间】:2016-10-05 02:23:32
【问题描述】:

在我的 EmberJS 应用程序中,我正在显示约会列表。在 AppointmentController 中的一个操作中,我需要获取约会所有者,但所有者总是返回“未定义”。

我的文件:

models/appointment.js

import DS from 'ember-data';

export default DS.Model.extend({
    appointmentStatus: DS.attr('number'),
    owner: DS.hasMany('person'),
    date: DS.attr('Date')
});

models/person.js

import DS from 'ember-data';

export default DS.Model.extend({
    name: DS.attr('string')
});

templates/appointmentlist.js

{{#each appointment in controller}}
    <div>
        {{appointment.date}} <button type="button" {{action 'doIt'}}>Do something!</button>
    </div>
{{/each }}

controllers/appointmentlist.js

export default Ember.ArrayController.extend({
    itemController: 'appointment'
});

controllers/appointment.js

export default Ember.ObjectController.extend({
    actions:{
        doIt: function(){
            var appointment = this.get('model');
            var owner = appointment.get('owner'); //returns undefined
            //Do something with owner
        }
    }
});

现在,我知道我可以将 owner-property 更改为 owner: DS.hasMany('person', {async: true}),然后处理从 appointment.get('owner'); 返回的承诺,但这不是我想要的。 我发现如果我在约会列表模板中执行此{{appointment.owner}} 或此{{appointment.owner.name}},则会从服务器获取所有者记录。所以我猜 Ember 不会加载关系,除非它们在模板中使用。

我认为我的问题的解决方案是使用约会列表路由来获取belongsTo关系中的记录。但我不知道怎么做。

也许是这样的?

routes/appointmentlist.js

export default Ember.Route.extend({
    model: function() {
        return this.store.find('appointment');
    },
    afterModel: function(appointments){
        //what to do
    }
});

编辑

我这样做了:

routes/appointmentlist.js

export default Ember.Route.extend({
    model: function() {
        return this.store.find('appointment');
    },
    afterModel: function(appointments){
         $.each(appointments.content, function(i, appointment){

                var owner= appointment.get('owner')   
         });
    }
});

它有效,但我不喜欢这个解决方案......

【问题讨论】:

    标签: ember.js ember-data


    【解决方案1】:

    您仍在异步加载这些记录,因此如果您的速度足够快,您仍然可能无法定义。最好从 afterModel 钩子返回一个承诺,或者只是修改模型钩子来完成这一切。

    model: function() {
      return this.store.find('appointment').then(function(appointments){
        return Ember.RSVP.all(appointments.getEach('owner')).then(function(){
          return appointments;
        });
      });
    }
    

    model: function() {
      return this.store.find('appointment');
    },
    afterModel: function(model, transition){
      return Ember.RSVP.all(model.getEach('owner'));
    }
    

    【讨论】:

      【解决方案2】:

      另一种方法是:

      export default Ember.Controller.extend({
        modelChanged: function(){
          this.set('loadingRelations',true);
          Ember.RSVP.all(this.get('model').getEach('owner')).then(()=>{
            this.set('loadingRelations',false);
          });      
        }.observes('model')
      });
      

      这样过渡完成得更快,然后关系被加载。加载状态可以通过loadingRelations观察。

      当有很多关系要加载时,我认为这会提供更好的用户体验。

      【讨论】:

      • 我已经有一段时间没有参与这个项目了,所以我无法在不久的将来测试你的解决方案。但这看起来很有趣,我有再次研究这个问题的冲动。
      【解决方案3】:

      您希望加载路径中的所有关联,因为您希望将 Fastboot 用于搜索引擎并获得更好的首次网站打开体验。

      在加载主要模型后保持关联加载可能不是最佳决定。

      我正在使用一种语法来加载路由中的所有关联:

         let store = this.store;
         let pagePromise = store.findRecord('page', params.page_id);
         let pageItemsPromise = pagePromise.then(function(page) {
           return page.get('pageItems');
         });
        return this.hashPromises({
          page: pagePromise,
          pageItems: pageItemsPromise
        });
      

      对于 this.hashPromises,我得到了一个 mixin:

          import Ember from 'ember';
      
          export default Ember.Mixin.create({
            hashPromises: function(hash) {
              let keys = Object.keys(hash);
      
              return Ember.RSVP.hashSettled(hash).then(function(vals) {
                let returnedHash = {};
                keys.forEach(function(key) {
                  returnedHash[key] = vals[key].value;
                });
                return returnedHash;
              });
            }
          });
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-07-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-11-29
        • 1970-01-01
        • 2021-06-06
        相关资源
        最近更新 更多