使用ember-data规范化嵌入式记录 [英] Normalize embedded records with ember-data

查看:89
本文介绍了使用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
},
{
活动: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的项目,
updated_at:2013-11-21T17:54:05.527808,
user_id:2
},
{
created_at:2013-11-21T17:54:29.557801,
id:3,
name:未来想法,
updated_at:2013-11-21T17:54:29.557816,
user_id:2
}
],
updated_at:2013-11-21T17:53:17.155717
}
]
}

我想更改JSON有效载荷,因此看起来像JSON响应,ember数据正在期待:我正在尝试从REST API归一化数据。我不会改变JSON响应。



如何通过这个JSON响应来解除嵌入式记录,使它们在一种侧装格式。服务器的响应如下所示:

  {
objects:[
{
active:true,
admin:true,
created_at:2013-11-21T15:12:37.894390,
email:me @ example 。
first_name:Joe,
id:1,
last_name:Joeson,
updated_at:2013-12 -06T19:50:17.035881
项目:[1]
},
{
活动: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 ]
}
],
项目:[
{
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的项目,
updated_at:2013-11-21T17:54:05.527808,
user_id:2
} ,
{
created_at:2013-11-21T17:54:29.557801,
id:3,
name:未来的想法,
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] = [];

有效载荷[embedKey] .push(embedObjs);

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

我的模型看起来像这样一个项目属于用户

  App.User = DS.Model。扩展({
active:DS.attr(),
admin:DS.attr(),
电子邮件:DS.attr(),
firstName:DS.attr ,
lastName:DS.attr(),
密码:DS.attr(),
createdAt:DS.attr(),
updatedAt:DS.attr(),
项目:DS.hasMany('project')
});
App.Project = DS.Model.extend({
createdAt:DS.attr(),
name:DS.attr(),
updatedAt:DS.attr() ,
userId:DS.belongsTo('user')
});

我在某个地方犯了一个错误,但我真的不知道哪里不在 extractSingle 。我在JavaScript控制台中收到以下错误:Assertion failed:加载路由时出错:TypeError:无法调用未定义的方法toString。我的应用程序在没有关系的情况下工作。

解决方案

在前面,刚刚手术,所以我一手交了很多氧可酮,所以代码可能需要重构,我会把它留给你..



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

 应用程式.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;
} e lse {
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 ]; //项目
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;
}
}
});


返回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;}

哈希[key] =哈希[payloadKey];
删除哈希[payloadKey];
},this);
}
},
keyForAttribute:function(attr){
return Ember.String.decamelize(attr);
}
});


I am trying to normalize data from REST API. I will not be changing the JSON response.

How do I generically munge this JSON response to pull out embedded records to make it so they are in a side-loaded format.

The response from the server looks like this:

{
  "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"
    }
  ]
}

I want to change JSON payload so it looks like the JSON response, ember-data is expecting:I am trying to normalize data from REST API. I will not be changing the JSON response.

How do generically munge this JSON response to pull out embedded records to make it so they are in a side-loaded format. The response from the server looks like this:

{
  "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
    }
  ]
}

So far I am extending 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);
     }
});

My models looks like this where a project belongs to a 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')
});

I am making a mistake somewhere, but I really don't know where other than it's in extractSingle. I get the following error in the JavaScript console, "Assertion failed: Error while loading route: TypeError: Cannot call method 'toString' of undefined." My app is working without the relations.

解决方案

Upfront, just had surgery, so I'm one handed and on a lot of oxycodone, so the code probably needs refactoring, I'll leave that up to you..

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);
  }
});

这篇关于使用ember-data规范化嵌入式记录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆