Ember-Cli:在 findAll() 查询前加上前缀

Ember-Cli: prepend a findAll() query with a prefix

在我的一条路线中,我需要 findAll() 用户的 Items,但不是发出标准 /items 请求,而是必须转到 /my/items

我目前的解决方案包括:

// routes/my/item.js
export default Ember.Route.extend({
    model() {
        this.store.unloadAll('item');
        return Ember.$.getJSON('/my/items').then((payload) => {
          this.store.pushPayload(payload);
          return this.store.peekAll('item');
        });
    }
});

但不幸的是,它并不理想,因为它需要 unloadAll() items 在发出请求之前确保模型仅 returns 新获取的记录,同时正在卸载任何缓存。

更好的解决方案可能涉及专门为此路由创建自定义适配器并覆盖 findAll() 方法或 urlForFindAll(),但我不确定如何正确创建和导入此类自定义适配器。

只是为了测试,我覆盖了默认的 Item 适配器并在路由模型中返回 findAll('item'),一切正常,请求以 /my/:

为前缀
// adapters/item.js
findAll: function(store, type, sinceToken, snapshotRecordArray) {
  var query, url;
  if (sinceToken) { query = { since: sinceToken }; }

  // prefix url with `my` str
  url = `my${this.buildURL(type.modelName, null, null, 'findAll')}`;
  return this.ajax(url, 'GET', { data: query });
},

// routes/my/item.js
export default Ember.Route.extend({
  model() {
    return this.store.findAll('item');
  }
});

..但这显然会覆盖该模型的所有 findAll() 查询,其中我只需要在此路径中进行自定义查询。

这可以通过使用 adapterOptions 将选项传递给使用 findAll 的项目适配器来解决:

1) 在路由中使用 adapterOption 将前缀传递给适配器:

return this.store.findAll('item', { adapterOptions: { prefix: 'my' } });

2) 在 ember-cli 中用 ember g adapter item 覆盖项目的默认适配器。

3) 在适配器中覆盖默认的 findAll 到前缀 url 如果传递了这样的选项:

// /app/adapters/item.js
import ApplicationAdapter from './application';

export default ApplicationAdapter.extend({
  findAll: function(store, type, sinceToken, snapshotRecordArray) {
    var query, url;
    if (sinceToken) { query = { since: sinceToken }; }

    let prefix = Ember.get(snapshotRecordArray, 'adapterOptions.prefix');
    url = `${prefix || ''}${this.buildURL(type.modelName, null, null, 'findAll')}`;

    return this.ajax(url, 'GET', { data: query });
  },
});

4) 成功,this.store.findAll('item', { adapterOptions: { prefix: 'my' } }); 现在将生成 my/items 而不是 items!