使用ember-data标准化嵌入的记录

时间:2013-12-10 17:44:07

标签: javascript ember.js ember-data

我正在尝试规范化REST API中的数据。 我不会更改JSON响应。

我如何通常使用此JSON响应来提取嵌入式记录,使其处于侧载格式。

服务器的响应如下所示:

{
  "objects": [
    {
      "active": true, 
      "admin": true, 
      "created_at": "2013-11-21T15:12:37.894390", 
      "email": "me@example.com", 
      "first_name": "Joe", 
      "id": 1, 
      "last_name": "Joeson", 
      "projects": [
        {
          "created_at": "2013-11-21T15:13:13.150572", 
          "id": 1, 
          "name": "Super awesome project", 
          "updated_at": "2013-11-21T15:13:13.150606", 
          "user_id": 1
        }
      ], 
      "updated_at": "2013-12-06T19:50:17.035881"
    }, 
    {
      "active": true, 
      "admin": false, 
      "created_at": "2013-11-21T17:53:17.155700", 
      "email": "craig@example.com", 
      "first_name": "Craig", 
      "id": 2, 
      "last_name": "Craigson", 
      "projects": [
        {
          "created_at": "2013-11-21T17:54:05.527790", 
          "id": 2, 
          "name": "Craig's project", 
          "updated_at": "2013-11-21T17:54:05.527808", 
          "user_id": 2
        }, 
        {
          "created_at": "2013-11-21T17:54:29.557801", 
          "id": 3, 
          "name": "Future ideas", 
          "updated_at": "2013-11-21T17:54:29.557816", 
          "user_id": 2
        }
      ], 
      "updated_at": "2013-11-21T17:53:17.155717"
    }
  ]
}

我想更改JSON有效负载,使其看起来像JSON响应,ember-data期待:我正在尝试规范化REST API中的数据。 我不会更改JSON响应。

如何通常使用此JSON响应来提取嵌入式记录,使其处于侧载格式。服务器的响应如下所示:

{
  "objects": [
    {
      "active": true, 
      "admin": true, 
      "created_at": "2013-11-21T15:12:37.894390", 
      "email": "me@example.com", 
      "first_name": "Joe", 
      "id": 1, 
      "last_name": "Joeson",  
      "updated_at": "2013-12-06T19:50:17.035881"
      "projects": [1]
    }, 
    {
      "active": true, 
      "admin": false, 
      "created_at": "2013-11-21T17:53:17.155700", 
      "email": "craig@example.com", 
      "first_name": "Craig", 
      "id": 2, 
      "last_name": "Craigson", 
      "updated_at": "2013-11-21T17:53:17.155717"
      "projects": [2, 3]
    }
  ],
  "projects": [
    {
      "created_at": "2013-11-21T15:13:13.150572", 
      "id": 1, 
      "name": "Super awesome project", 
      "updated_at": "2013-11-21T15:13:13.150606", 
      "user_id": 1
    },
    {
      "created_at": "2013-11-21T17:54:05.527790", 
      "id": 2, 
      "name": "Craig's project", 
      "updated_at": "2013-11-21T17:54:05.527808", 
      "user_id": 2
    }, 
    {
      "created_at": "2013-11-21T17:54:29.557801", 
      "id": 3, 
      "name": "Future ideas", 
      "updated_at": "2013-11-21T17:54:29.557816", 
      "user_id": 2
    }
  ]
}

到目前为止,我正在扩展DS.RESTSerializer

App.ApplicationSerializer = DS.RESTSerializer.extend({
    extractArray: function(store, type, payload, id, requestType) {
        var result = {};
        result[type.typeKey] = payload.objects;
        payload = result;

        return this._super(store, type, payload, id, requestType);
    },
    extractSingle: function(store, type, payload, id, requestType) {
        var result;
        var model = type.typeKey;

        if (payload.object) {
            result = payload.object;
        } else {
            result = payload;
        }

        var embedObjs, embedKey;

        type.eachRelationship(function(key, relationship) {
            if (relationship.kind === 'hasMany') { 
                embedKey = key;
                for (var i = 0; i < result[key].length; i++) {
                    result.key.push(result[key][i].id);
                }
                embedObjs = result[key].pop();
            }
        });

        payload[model] = result;

        if (!payload[embedKey])
            payload[embedKey] = [];

        payload[embedKey].push(embedObjs);

        return this._super(store, type, payload, id, requestType);
     }
});

我的模型看起来像project属于user

App.User = DS.Model.extend({
    active: DS.attr(), 
    admin: DS.attr(),  
    email: DS.attr(), 
    firstName: DS.attr(),  
    lastName: DS.attr(),
    password: DS.attr(),
    createdAt: DS.attr(),  
    updatedAt: DS.attr(),
    projects: DS.hasMany('project')
});
App.Project = DS.Model.extend({
    createdAt: DS.attr(), 
    name: DS.attr(), 
    updatedAt: DS.attr(),
    userId: DS.belongsTo('user')
});

我在某个地方犯了一个错误,但我真的不知道extractSingle中的其他地方。我在JavaScript控制台中收到以下错误:“断言失败:加载路径时出错:TypeError:无法调用未定义的方法'toString'。”我的应用程序没有关系。

1 个答案:

答案 0 :(得分:5)

Upfront,刚刚进行了手术,所以我只是一手拿着很多羟考酮,所以代码可能需要重构,我会把它留给你......

http://emberjs.jsbin.com/OxIDiVU/9/edit

App.ApplicationSerializer = DS.RESTSerializer.extend({
    extractArray: function(store, type, payload, id, requestType) {
        var result = {};
        result[ Ember.String.pluralize(type.typeKey)] = payload.objects;
        payload = result;
     //   debugger;
        return this._super(store, type, payload, id, requestType);
    },
    normalizePayload: function(type, payload) {

        var result;
        var typeKey = Ember.String.pluralize(type.typeKey);

        if (payload.object) {
            result = payload.object;
        } else {
            result = payload;
        }

        var typeArr =result[typeKey];

        type.eachRelationship(function(key, relationship) {
            if (relationship.kind === 'hasMany') { 
              var arr = result[key]=[];
              for(var j=0, jlen = typeArr.length;j<jlen;j++){
                var obj = typeArr[j]; //user
                var collection = obj[key];//projects
                var ids = [];
                for (var i = 0, len=collection.length; i < len; i++) {
                  var item = collection[i];
                  arr.push(item);
                  ids.push(item.id);
                }
                obj[key]=ids;
              }
            }
        });


      return this._super(type, result);
    },
   normalizeAttributes: function(type, hash) {

    var payloadKey, key;
    if (this.keyForAttribute) {
      type.eachAttribute(function(key) {

        payloadKey = this.keyForAttribute(key);
        if (key === payloadKey) { return; }

        hash[key] = hash[payloadKey];
        delete hash[payloadKey];
      }, this);
    }
  },
  keyForAttribute: function(attr) {
    return Ember.String.decamelize(attr);
  }
});