Ember {include:property}和Strongloop

时间:2015-11-25 12:00:47

标签: ember.js ember-data ember-cli strongloop

好的,这就是事情,因为我更多地了解Ember和StrongLoop集成,我发现连接它们越来越困难。

我现在有以下问题。 StrongLoop不会返回基于JSONAPI格式的模型关系,因此如果我的video模型与hasMany模型之间存在tag关系,则我的include数组不会响应如下:JSON API docs

所以我必须在这里选择:async: true发出2个请求并且不可取,或者将过滤器参数传递给请求,如:

return this.store.queryRecord('video', {'include': 'tag'});会向/videos?include=tag发送请求,但StrongLoop无法识别此请求。

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

要将StrongLoop响应格式化为json:api,请安装优秀的loopback-component-jsonapi并使用

创建server/component-config.json文件
{
  "loopback-component-jsonapi": {}
}

我喜欢驼峰式ReST apis,所以我配置了Ember JSONAPIAdapter就像这样

import Ember from 'ember';

export default DS.JSONAPIAdapter.extend({

  // Where our API lives on our URI
  namespace: 'api',

  // change default from dasherize to camelize
  pathForType(type) {
    var camelized = Ember.String.camelize(type);
    return Ember.String.pluralize(camelized);
  }
});

在您的Ember视频模型中添加tags: hasMany('tag')后,由于关系链接位于响应中,您可以:

{{#each model.tags as |tag|}}
...
{{/each}}

当然,这种方法会为每个标签提出单独的ajax请求 - 在某些情况下可能有效,而在其他情况下则无效。

StrongLoop在json:api标准之前开发了他们的过滤器语法,所以它有点不同。他们的过滤器必须包含filter查询参数键。我更喜欢使用json,因为它更容易阅读并且与Ember一起使用。

var query = {filter: {where: {createdBy:'starver', 
                              updatedBy:'service_acct'},
                      limit: 30
            }};
return this.store.query('mymodel', query);

如果您的查询参数已经传递到您的路径中,您可以在过滤器中使用它们,假设它们被构造为使用环回:

model(params) {
  var query = {filter: {where: params,
                        limit: 45
              }};
  return this.store.query('subscription', query);
}

StrongLoop中的侧面加载数据如下所示:

http://localhost:3000/api/subscriptions/1475?filter[include]=subscriptionStatus

在ember中,您可以将字符串作为查询传递,但v2.7.0破坏了此功能。有一个解决方法:在JSONAPIAdapter配置中禁用查询参数排序:

  // prevent the default implementation from turning a string into an array
  sortQueryParams: function(params) {
    return params;
  }

然后您的路线模型查询如下:

return this.store.query('view', 'filter[include]=tag');

jQuery在作为对象传递时会破坏更复杂的查询过滤器 - 它将过滤器对象分解为一系列对StrongLoop没有任何意义的过滤查询参数。解决此问题的一种方法是将查询过滤器形成为js对象,然后将其形成为JSON.stringify()。

使用JSON.stringify()方法,将数据从一个表包含到另一个表的另一种方法是将该数据包含在响应的属性部分中。以下是工作代码的示例:

var query = {
  include: {
    relation: "subscriptionStatus",
    scope: {
      fields: ["subscriptionStatus"],
      where: {
        endDate: null
      }
    }
  },
  limit: 45
};
return this.store.query('subscription', 'filter=' + JSON.stringify(query));

这会产生一个看起来像

的属性部分
"attributes": {
  "createdBy": "services",
  "createdTs": "2016-07-27T21:37:50.000Z",
  "updatedBy": "services",
  "updatedTs": "2016-07-27T21:58:04.000Z",
  "version": 9,
  "certificateId": 1,
  "backupTime": "0:0",
  "backupRetentionDays": 1,
  "subscriptionStatus": [
    {
      "subscriptionStatus": "TERMINATED",
      "subscriptionId": 1475
    }
  ]
},

这很有趣,但在ember约定中提出了一些名称冲突问题。

这是一个非常古老的问题,但也许它会帮助有人解决这些问题。

StrongLoop查询文档:https://docs.strongloop.com/display/public/LB/Querying+data#Queryingdata-UsingstringifiedJSONinRESTqueries

注意:我使用的是loopback v2.14.0,ember v2.7.0(同样适用于2.5,2.6)