7

Ember.js REST 适配器期望 JSON 返回为:

{
    "person": {
        "first_name": "Barack",
        "last_name": "Obama",
        "is_person_of_the_year": true
    }
}

但是我的 API 返回的数据没有根元素

{
    "first_name": "Barack",
    "last_name": "Obama",
    "is_person_of_the_year": true
}

是否可以自定义 REST 适配器以便它接受我的 JSON 数据?现在它显示“断言失败:您的服务器返回了一个带有密钥 0 的哈希,但您没有它的映射

更新: 根据 Sherwin Yu 在下面的回答,这是我想出的,到目前为止似乎有效:https ://gist.github.com/richardkall/5910875

4

5 回答 5

15

您还可以将其规范化为 ember 所期望的内容。

App.PersonSerializer = DS.RESTSerializer.extend({
  normalizePayload: function(type, payload) {
    var typeKey = type.typeKey;
    return {
      typeKey: payload
    }
  }
});
于 2013-12-15T12:41:24.720 回答
8

是的,您可以编写自己的自定义 REST 适配器。查看JSONSerializerRESTSerializer(它扩展了 JSONSerializer)和REST 适配器中的源代码。

基本上,您需要覆盖 extract*JSONSerializer 中的方法。

目前,它看起来像这样:

extract: function(loader, json, type, record) {
  var root = this.rootForType(type);

  this.sideload(loader, type, json, root);
  this.extractMeta(loader, type, json);

  if (json[root]) {
    if (record) { loader.updateId(record, json[root]); }
    this.extractRecordRepresentation(loader, type, json[root]);
  }
},

请注意它是如何检查json[root]的——您必须根据预期的 API 响应编写自定义方法。

另一种方法是“预处理”来自 API 的 json 以使用根元素。您可以通过找出调用的方法extract*(将 json 传递给它)并在它这样做之前修改 json 以包含根元素来做到这一点。

希望这会有所帮助,如果不清楚,请告诉我。

于 2013-07-02T15:39:09.533 回答
1

我通过扩展 DS.RESTSerializer 解决了这个问题。当服务器响应为数组类型时,需要重载 extractArray 方法。

App.PersonSerializer = DS.RESTSerializer.extend({
    extractSingle: function (store, type, payload, id) {
        var wrappedObj = {};
        wrappedObj[type.typeKey] = payload;
        return this._super(store, type, wrappedObj, id);
    }});
于 2015-03-31T03:28:23.373 回答
1

最简单的方法是不使用 RESTSerializer,而是使用更简单的 JSONSerializer,它不需要根元素。

可以在以下两篇博客文章中找到有关了解用于给定 API 的序列化程序的良好资源:

http://thejsguy.com/2015/12/05/which-ember-data-serializer-should-i-use.html
http://emberigniter.com/fit-any-backend-into-ember-custom-adapters -序列化器/

于 2016-07-07T16:08:40.640 回答
-1

我试图将root添加到json。这对我有用:

App.Adapter = DS.RESTAdapter.extend({
    findAll: function(store, type, since) {
        var root, adapter;
            var plural; // Insert this line
        root = this.rootForType(type);
        adapter = this;
            plural = this.pluralize(root); // Insert this line
        return this.ajax(
                this.buildURL(root), 
                "GET",
                {
                    data: this.sinceQuery(since)
                }).then(function(json) {
                    eval ( "json = {" + plural + " : json }" ); // Insert this line
                    adapter.didFindAll(store, type, json);
                }).then(null, DS.rejectionHandler);
    }
});
于 2013-09-10T04:09:50.357 回答