在模型钩子中获取异步hasMany关系

时间:2014-08-09 13:15:01

标签: ember.js ember-data

假设我有两个模型,BookChapter

App.Book = DS.Model.extend({
  name: DS.attr(),
  chapters: DS.hasMany('chapter', { async: true })
});

App.Chapter = DS.Model.extend({
  name: DS.attr(),
  book: DS.belongsTo('book')
});

我正在使用RESTAdapter

App.ApplicationAdapter = DS.RESTAdapter;

IndexRoute中,我想说我想获取第一本书(id = 1)及其相关章节。由于hasMany关系标记为async: true,因此我想在呈现模板之前获取此关联。

App.IndexRoute = Ember.Route.extend({
  model: function() {
    return Ember.RSVP.hash({
      book: this.store.find('book', 1)
    }).then(function(hash) {
      hash.chapters = hash.book.get('chapters');
      return hash;
    })
  },
  setupController: function(controller, model) {
    controller.set('model', model.book);
  }
});

我的索引模板只显示书名,并迭代其章节。

<script type="text/x-handlebars" id="index">
  <h3>Book: {{name}}</h3>

  <ul>
    {{#each chapters}}
      <li>{{name}}</li>
    {{/each}}
  </ul>
</script>

使用mockjax时,我设置了模拟响应。

$.mockjax({
  url: '/books/1',
  responseText: {
    book: {
      id: 1,
      name: 'Book 1',
      chapters: [1, 2]
    }
  }
});

$.mockjax({
  url: '/chapters?ids[]=1&ids[]=2',
  responseText: {
    chapters: [{
      id: 1,
      name: 'Chapter 1',
      book_id: 1
    }, {
      id: 2,
      name: 'Chapter 2',
      book_id: 1
    }]
  }
});

问题1:According to the RESTAdapter docs,访问book.get('chapters')应向/chapters?ids[]=1&ids[]=2发出GET请求。 但是,我的控制台向/chapters/1/chapters/2显示了两个单独的请求。

问题2:此外,我相信模板在章节请求发生之前呈现,因为在我看到对/chapters/1和{/chapters/2的两个请求之前,模板呈现了一两秒。 {1}}。如果我从路由中删除对hash.book.get('chapters')的调用,则会出现同样的问题。 换句话说,我认为路线不发送请求,我认为模板是

Here is a jsbin。您会注意到它没有显示任何章节,因为我没有设置它要求的两条路线(/chapters/1/chapters/2)。

1 个答案:

答案 0 :(得分:1)

第一个问题的原因很简单:您使用了Ember Data的Dev(Canary)版本,其行为与您在EmberJS网站上可以找到的beta版本不同。这是最前沿的,所以很难判断它是否被打破或者这些是否即将发生变化。如果您希望行为与指南一致,我建议使用最新的beta版本(Ember Data尚未标记为稳定版)。

至于第二个问题:由于您正在使用异步请求和Promises,因此这是理想的行为。这意味着,您立即返回结果(无需等待任何内容),但在解决异步请求之前,这些结果为空

你可以包装这种行为,并且(例如)只在你的异步例程完成时注入一个模板,但是我会建议重新考虑它,因为根据个人经验它不是常见的模式,很可能你的应用程序没有&# 39;不需要它。

如果您对这些机制的确切运作方式感兴趣(您不需要这样做,那只是为了满足对主题的潜在好奇心):