使用ember-data规范化嵌入式记录 [英] Normalize embedded records with ember-data
问题描述
我如何通用这个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屋!