正确格式化侧载JSON API数据的Ember自定义序列化程序响应

时间:2017-12-13 21:36:44

标签: ember.js ember-data

我想尝试将sideloaded data投放到我的Ember应用中。我有一个city模型hasMany fireStations。我将hasMany关系更改为具有{ async: false }选项以与sideloading一致,因为数据将不再异步加载。

我使用自定义序列化程序,我正在记录normalize()的响应。我的数据看起来像这样。

{
  "data": {
    "id": "3",
    "type": "city",
    "attributes": {
      "name": "Anytown USA"
    },
    "relationships": {
      "fireStations": {
        "data": [
          {
            "id": "17",
            "type": "fire-station"
          },
          {
            "id": "18",
            "type": "fire-station"
          }
        ]
      }
    }
  },
  "included": [
    {
      "id": "17",
      "type": "fire-station",
      "attributes": {
        "name": "North Side Fire Station"
      },
      "relationships": {}
    },
    {
      "id": "18",
      "type": "fire-station",
      "attributes": {
        "name": "East Side Fire Station"
      },
      "relationships": {}
    }
  ]
}

认为我的侧载数据格式正确。它似乎与example in the guides匹配。 included数组中填充了我所有的侧载数据,并且所有数据似乎都根据需要进行了格式化。

但是,我在我的应用中遇到了这个错误。

  

断言失败:你抬头看了火灾台'一个城市的关系' id为3,但未加载某些相关记录。要么确保它们都与父记录一起加载,要么指定关系是异步的(' DS.hasMany({async:true})')

根据JSON API规范,我正在使用的格式对于加载compound documents似乎是正确的。

  

在复合文档中,所有包含的资源必须表示为顶级included成员中的资源对象数组。

似乎links是可选的,所以我将它们排除在外应该没问题。

  

每个资源对象中的可选links成员包含与资源相关的链接。

我无法弄清问题是什么。我在本地分叉ember-data,我确实看到this assertion is triggered

如果我手动循环manyArray中的has-many.js,我会看到每条记录都标记为isEmptytrue

为什么has-many记录会返回isEmpty === true?我可能做错了什么阻止了侧载正常工作?

1 个答案:

答案 0 :(得分:0)

我能够创建Ember Twiddle来查找,重新创建和解决我的问题。

简短回答是我的自定义序列化程序在规范化期间丢弃了included。我混淆了normalize()normalizeResponse()之间的责任,并从错误的方法返回included

我试图在included的哈希上设置normalize()属性(这就是我在上面的问题中看到的)。这种做法完全错了。

如果需要,included的响应中应该出现

normalizeResponse()。所以我(多余)在included中有response(),但在normalizeResponse()实际需要它的地方没有。

normalizeResponse (store, primaryModelClass, payload, id, requestType) {
  let { data, included } = this._super(...arguments);

  // Do some manipulation on `data` or `included`.

  // Oh no! We lost the `included` array!
  // This will cause an error
  // because we are saying the
  // relationship is not async, but we're
  // dropping the `included` data!
  return { data };

  // This is what we want, for this contrived example.
  // return { data, included };
}

如果需要返回included数组,则应从normalizeResponse()返回,而不是normalize()。对于那些查看JSONAPISerializer in json-api.js源代码的人来说,这一点应该是显而易见的,但我一路上都迷路了。

the JSONAPISerializer implementation for ember-data 2.17.0中,您可以看到includeddocumentHash调用的方法中设置了normalizeResponse()

我的序列化程序执行批次自定义,因为我的API非常不标准,我在这里误解了一些细节。此外,我认为尽管有文档,但在each of the various normalize... API hooks中应该和不应该做什么有点困难。虽然,我想如果我花更多时间阅读它们,我可能会理解这一点。