我需要一次性将一个深层对象保存到服务器,并且无法在线找到任何使用最新ember数据(1.0.0-beta.4)的示例。
例如,使用这些模型: (jsfiddle)
App.Child = DS.Model.extend({
name: DS.attr('string'),
age: DS.attr('number'),
toys: DS.hasMany('toy', {async:true, embedded:'always'}),
});
App.Toy = DS.Model.extend({
name: DS.attr('string'),
child: DS.belongsTo('child')
});
这段代码:
actions: {
save: function(){
var store = this.get('store'),
child, toy;
child = store.createRecord('child', {
name: 'Herbert'
});
toy = store.createRecord('toy', {
name: 'Kazoo'
});
child.set('toys', [toy]);
child.save();
}
}
它只保存子对象的JSON,但不保存任何玩具 - 甚至没有侧载:
{
child: {
age: null
name: "Herbert"
}
}
我是否还必须手动保存玩具?无论如何,我可以让它将以下JSON发送到服务器:
{
child: {
age: null
name: "Herbert",
toys: [{
name: "Kazoo"
}]
}
}
或者
{
child: {
age: null
name: "Herbert",
toys: [1]
}
}
参见JSFiddle:http://jsfiddle.net/jgillick/LNXyp/2/
答案 0 :(得分:9)
这里的答案已经过时了。 Ember Data现在支持嵌入式记录,这使您可以完成您正在寻找的事情,即在一个大的有效负载中获取和发送完整的对象图。例如,如果您的模型设置如下:
App.Child = DS.Model.extend({
name: DS.attr('string'),
age: DS.attr('number'),
toys: DS.hasMany('toy')
});
App.Toy = DS.Model.extend({
name: DS.attr('string'),
child: DS.belongsTo('child')
});
您可以为您的Child模型定义自定义序列化程序:
App.ChildSerializer = DS.RESTSerializer.extend(DS.EmbeddedRecordsMixin, {
attrs: {
toys: {embedded: 'always'}
}
});
这告诉Ember Data你喜欢玩具'被列为“孩子”的一部分。有效载荷。您的API的HTTP GET响应应如下所示:
{
"child": {
"id": 1,
"name": "Todd Smith",
"age": 5,
"toys": [
{"id": 1, "name": "boat"},
{"id": 2, "name": "truck"}
]
}
}
当您保存模型时,Ember Data会将其发送到服务器:
{
"child":{
"name":"Todd Smith",
"age":5,
"toys":[
{
"id":"1",
"name":"boat",
"child":"1"
},
{
"id":"2",
"name":"truck",
"child":"1"
}
]
}
}
这是一个证明这一点的JSBin。
http://emberjs.jsbin.com/cufaxe/3/edit?html,js,output
在JSbin中,当您点击'保存'按钮,您需要使用Dev Inspector查看发送到服务器的请求。
答案 1 :(得分:3)
玩具不能同时是异步和嵌入,这些都是矛盾的选择。嵌入式仅存在于当前的活动模型序列化程序中。
toys: DS.hasMany('toy', {embedded:'always'})
玩具是ManyToOne关系,并且由于关系存在于belongsTo方面,因此在玩具保存期间保存关系更有效。话虽这么说,如果你是一次性创建它,那么就想把它保存在一个大块中,这是重写发挥作用的地方。
serializeHasMany: function(record, json, relationship) {
var key = relationship.key;
var relationshipType = DS.RelationshipChange.determineRelationshipType(record.constructor, relationship);
if (relationshipType === 'manyToNone' || relationshipType === 'manyToMany' ||
relationshipType === 'manyToOne') {
json[key] = get(record, key).mapBy('id');
// TODO support for polymorphic manyToNone and manyToMany relationships
}
},
你的保存应该是这样的
var store = this.get('store'),
child, toy;
child = store.createRecord('child', {
name: 'Herbert'
});
toy = store.createRecord('toy', {
name: 'Kazoo'
});
child.get('toys').pushObject(toy);
child.save().then(function(){
toy.save();
},
function(err){
alert('error', err);
});
答案 2 :(得分:0)
我需要一个深层物体,而不是侧面物体,所以基于kingpin2k的答案,我想出了这个:
DS.JSONSerializer.reopen({
serializeHasMany: function(record, json, relationship) {
var key = relationship.key,
property = Ember.get(record, key),
relationshipType = DS.RelationshipChange.determineRelationshipType(record.constructor, relationship);
if (property && relationshipType === 'manyToNone' || relationshipType === 'manyToMany' ||
relationshipType === 'manyToOne') {
// Add each serialized nested object
json[key] = [];
property.forEach(function(item, index){
json[key].push(item.serialize());
});
}
}
});
现在,当您致电child.serialize()
时,它将返回此对象:
{
child: {
name: "Herbert",
toys: [
{
name: 'Kazoo'
}
]
}
}
这就是我需要的。以下是jsfiddle的实际应用:http://jsfiddle.net/jgillick/LNXyp/8/