从ember数据查询中访问`links`属性

时间:2015-11-23 07:40:45

标签: ember.js ember-data json-api

使用JSONAPIAdaper时,我在商店中查询模型,服务器响应包含json-api spec指定的"links"属性,响应如此。

{
  "links": {
    "self": "http://localhost:4200/api/v0/blog-posts?size=10",
    "first": "http://localhost:4200/api/v0/blog-posts?size=10&page=0",
    "last": "http://localhost:4200/api/v0/blog-posts?size=10&page=1",
    "next": "http://localhost:4200/api/v0/blog-posts?size=10&page=1"
  },
  "data": [{
    "id": 1,
    "type": "blog.posts",
    "attributes": {
      "published": "2015-04-04T00:56:36.768Z"
    },
    "relationships": {
      "revisions": {
        "data": [
          { "id": 1, "type": "blog.post.revisions" },
          { "id": 2, "type": "blog.post.revisions" },
          { "id": 3, "type": "blog.post.revisions" },
          { "id": 4, "type": "blog.post.revisions" }
        ]
      },
      "current": {
        "data": { "id": 4, "type": "blog.post.revisions" }
      }
    }
  }]
}
  

注意:我删除了data属性中的大多数元素,并删除了包含的属性,因为它们使示例不必要地变大。 同样不要担心类型名称,不可否认它们看起来很奇怪,但这就是我设置序列化器的方式(以反映pod结构)。

请求它的路由看起来像这样

import Ember from 'ember';


export default Ember.Route.extend({
  model () {
    const store = this.get('store');
    return store.query('blog.post', { size: 10 });
  }
});

我所做的是通过用链接属性中指定的链接中的数据替换模型,为我的博客制作分页机制。

如何访问此"links"属性?

版本

  • ember @ 2.2
  • ember-data @ 2.2

1 个答案:

答案 0 :(得分:1)

解决方案

我最终扩展了序列化器,并在记录数组规范化后在links对象中插入meta对象。

// pods:    app/application/serialiser.js
// vanilla: app/serialisers/application.js
import DS from 'ember-data';

export default DS.JSONAPISerializer.extend({
  /**
   * will attach links to the meta object
   */
  normalizeArrayResponse (...args) {
    const normalized = this._super(...args);
    //
    // since the meta object is optional, it's
    // best to verify if it's null/undefined
    //
    if (normalized.meta == null) {
      normalized.meta = {};
    }
    normalized.meta.links = normalized.links;
    return normalized;
  }
});

所以在我的路线中,我可以访问像这样的对象的链接

import Ember from 'ember';

export default Ember.Route.extend({
  model (params) {
    const store = this.get('store');
    return store.query('blog.post', params).then(posts => {
      //
      // access the links object like so.
      //
      const links = posts.get('meta.links');
      return Ember.Object.create({ links, posts })
    });
  }
});

注意事项

这不是最佳解决方案,因为它可能会覆盖links对象中名为meta的任何属性。

解决此问题的一种方法是使用符号作为字段名称,因为符号是唯一的,因此您可以确定不会覆盖对象名称空间中的任何现有名称。但是我没有试过这个,它可能在旧浏览器上不能很好地工作,我不确定ember的get方法如何与符号交互。