Ember.js v2 在路由中加载多个模型而不单独请求

Ember.js v2 Load multiple models in route without making separate requests

刚开始接触Ember.js,所以在网上看了几个星期的各种教程之后(…),我真的想不通下面的问题。

我想在 1 条路线上显示 4 个模型。我该怎么做,同时避免进行 4 次服务器调用?

更多信息:

我想在我的索引页面上显示 "person"、"quote"、"product" 和 "case" 类型的记录。

在我的索引路由中,(routes/index.js) 我可以使用以下方式加载它们:

import Ember from "ember";

export default Ember.Route.extend({
  model(){
    return Ember.RSVP.hash({
      persons : this.get('store').findAll('person'),
      quotes  : this.get('store').findAll('quote'),
      cases   : this.get('store').findAll('case'),
      products: this.get('store').findAll('product')
    });
  }
});

(在我的适配器中,adapters/application.js,我有:)

import DS from "ember-data";

export default DS.JSONAPIAdapter.extend({
  host       : 'http://localhost:8080/dummy.php',
  pathForType: function (type) {
    return "?type=" + type;
  }
});

这很好用 :),但是 ember.js 提出了 4 个请求:

但是,我可以轻松地提供一个 JSON 文件,其中包含所有 4 种类型的记录。

所以,我怎么知道 ember.js:

"Here's a nice large JSON file, full of records. Now, use only records of the 'person'-type for the person model, and idem dito for 'case', 'quote' and 'product'

?

好吧,您可能可以在您的适配器中实现它。这可以让您了解您可以做什么:

export default DS.JSONAPIAdapter.extend({
  init() {
    this._super(...arguments);
    this.set('toLoad', {});
  },

  loadDebounces() {
    const toLoad = this.get('toLoad');
    this.set('toLoad', {});
    const keys = Object.keys(toLoad);

    const data = magicLoadForAllAllKeys(); // just do something you like here. Sent the keys as POST, or GET array, websockets, smoke signals..
    Object.keys(data).forEach(key => {
      toLoad[key].resolve(data[key]);
    });
  },

  findAll (store, type, sinceToken, snapshotRecordArray)  {
    return new Ember.RSVP.Promise((resolve, reject) => {
      this.set(`toLoad.${type}`, { resolve, reject });
      Ember.run.debounce(this, this.loadDebounces, 1);
    });
  },
});

您基本上可以去除多个请求并将它们作为一个处理。然而,这既不符合 RESTFull 标准,也不符合 JSONAPI 标准。顺便提一下。

按请求加载模型没有错。如果模型相关,那么您应该考虑在它们之间定义 relationship。再次加载任何异步数据,它将发出网络请求。

如果你想为不同的模型类型在单个请求中加载数据,那么你可以尝试下面的方法,这不是 ember-data 方式。所以我不会鼓励这个。

import Ember from "ember";

const {RSVP} = Ember;

export default Ember.Route.extend({
  model() {
    return RSVP
      .resolve(Ember.$.getJSON('http://localhost:8080/dummy.php'))
      .then((result) => {
        this.get('store').pushPayload(result);
        return {
          persons : this.get('store').peekAll('person'),
          quotes  : this.get('store').peekAll('quote'),
          cases   : this.get('store').peekAll('case'),
          products: this.get('store').peekAll('product')
        };
      });
  }
});