我想知道使用createRecord()
在Ember中创建新记录然后将其持久化到API的最佳做法?具体来说,Ember的POST
请求通常是一个嵌入所有模型关系的JSON,还是每个关系单独POST
的习惯?
在我的代码中,我无法获得单个JSON,所以我想知道我是否错过了“Ember Way”或者(更有可能)我的代码中有错误?
详情:
以下是我的设置的详细信息。我有两个模型:
/models/OrgUser.js:
DS.Model.extend({
...
orgPerson: DS.belongsTo('org-person', { inverse: 'org-user', async: true, embedded: 'always' }),
});
/models/OrgPerson.js:
DS.Model.extend({
...
orgUser: DS.belongsTo('org-user'),
})
我正在尝试在“创建新用户”页面上创建新用户。该页面的路线如下。这是为我的新模特致电createRecord()
的最佳地点吗?
/routes/org-users/add.js:
Ember.Route.extend({
model: function() {
var orgPerson = this.store.createRecord('org-person');
var orgUser = this.store.createRecord('org-user' );
orgUser.set('orgPerson', orgPerson);
return orgUser;
},
...
}
在我致电set
后,使用Chrome控制台查看orgUser对象,完全没有显示我已向orgUser
添加任何内容的证据。不过,Chrome调试工具的“Ember”标签确实反映了这种关系。
在我的“创建新用户”页面上,我的输入字段都对应OrgUser
属性和OrgUser.OrgPerson
属性。这是一个例子:
/templates/org-users/add.hbs
...
{{input value=username}} // a property of OrgUser
{{input value=orgPerson.firstName}} // a property of OrgUser.orgPerson
...
在我的路线中,当我转到save()
Ember数据POST
时,只有null
orgPerson.
值为orgPerson
的orgUser JSON我希望它嵌入orgPerson
属性中的Ember.Route.extend({
...
actions: {
submitForm: function() {
...
this.currentModel.save().then( onSuccess ).catch( onFailure );
...
}
}
});
序列化对象。
/routes/org-users/add.js:
POST
这导致{
"orgUser":{
"username":"MyUsername",
"orgPerson":null,
"id":null
}
请求包含以下正文:
orgPerson
请注意DS.RESTSerializer.extend({
// Use the default approach to serializing, but add the id property
serialize: function(record, options) {
var json = this._super.apply(this, arguments);
json.id = record.id;
return json;
},
serializeBelongsTo: function(record, json, relationship) {
var key = relationship.key;
key = this.keyForRelationship ? this.keyForRelationship(key, 'belongsTo') : key;
var data = record.get('data');
if (relationship.options.embedded && relationship.options.embedded === 'always') {
json[key] = data[relationship.key] ? data[relationship.key].serialize( { includeId: true } ) : null;
}
else {
json[key] = data[relationship.key] ? data[relationship.key].get('id') : null;
}
if (relationship.options.polymorphic) {
this.serializePolymorphicType(record, json, relationship);
}
}
});
为空。提前感谢您的任何帮助!
更新:再一次,我想我需要重新审视一下我的序列化程序。以下是它当前的定义方式。
/serializers/application.js:
serialize()
Per @ Kingpin2k的评论,似乎有一些歧义(和错误!)关于如何最好地处理belongsTo
关系的this.store.find()
。我上面的序列化程序自定义适用于通过createRecord()
获取的记录,但现在我需要为{{1}}启用它们。其他建议,欢迎指点!
答案 0 :(得分:1)
这是一个错误。 https://github.com/emberjs/data/issues/1542#issuecomment-49443496
解决方法是在尝试保存之前获取异步的belongsTo记录(它将Ember数据用于初始化)。在你的情况下,你可以在模型钩子中完成它。
model: function() {
var orgPerson = this.store.createRecord('org-person');
var orgUser = this.store.createRecord('org-user');
orgUser.set('orgPerson', orgPerson);
return orgUser.get('orgPerson').then(function(){
return orgUser;
});
},
答案 1 :(得分:0)
所以,我终于弄明白了。随着Ember-Data-1.0.0-Beta.9,http://emberjs.com/blog/2014/08/18/ember-data-1-0-beta-9-released.html的发布,EmbeddedRecordsMixin
已被引入。这几乎解决了我的所有问题!
所以,我做了以下事情:
serializeBelongsTo
自定义EmbeddedRecordsMixin
为每个模型定义自定义序列化程序。 这完美地完成了,因为我可以完全控制我的记录嵌入的方式和时间。
特别感谢@Kingpin2k帮助我实现我的序列化程序是问题,并让讨论帮助我理解选项。