Javascript 不带JSON根的Ember.js REST适配器

Javascript 不带JSON根的Ember.js REST适配器,javascript,json,api,ember.js,ember-data,Javascript,Json,Api,Ember.js,Ember Data,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"

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下面的回答,这是我想到的,到目前为止似乎有效:

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

基本上,您需要重写JSONSerializer中的
extract*
方法

目前,它看起来像这样:

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以包含根元素


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

我尝试将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);
    }
});

您还可以将其正常化为余烬所期望的内容

App.PersonSerializer = DS.RESTSerializer.extend({
  normalizePayload: function(type, payload) {
    var typeKey = type.typeKey;
    return {
      typeKey: payload
    }
  }
});

我通过扩展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);
    }});

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

在以下两篇博文中可以找到关于理解给定API使用哪种序列化程序的有用资源:



太棒了!非常感谢你!这似乎是可行的:操作响应属于序列化程序,而不是适配器。
type
不再可用,只是
payload
。与公认的答案相比,这是一条路,因为开发人员不必担心有效负载的类型(数组、单个对象),也不必担心任何存储操作。这是正确的想法,但代码不起作用。返回值的键是字面上的“typeKey”,而不是由
var-typeKey
存储的值。