Javascript 从createRecord()save()序列化中省略了Ember Data belongsTo异步关系
编辑11/16/14:版本信息Javascript 从createRecord()save()序列化中省略了Ember Data belongsTo异步关系,javascript,ember.js,ember-data,rsvp-promise,Javascript,Ember.js,Ember Data,Rsvp Promise,编辑11/16/14:版本信息 DEBUG: Ember : 1.7.0 ember-1.7.0.js:14463 DEBUG: Ember Data : 1.0.0-beta.10+canary.30d6bf849b ember-1.7.0.js:14463 DEBUG: Handlebars : 1.1.2 ember-1.7.0.js:14463 DEBUG: jQuery : 1.10.2 我正试图用灰烬和灰烬数据做一些我认为应该相当简单的事情,但我到目前为止还没
DEBUG: Ember : 1.7.0 ember-1.7.0.js:14463
DEBUG: Ember Data : 1.0.0-beta.10+canary.30d6bf849b ember-1.7.0.js:14463
DEBUG: Handlebars : 1.1.2 ember-1.7.0.js:14463
DEBUG: jQuery : 1.10.2
我正试图用灰烬和灰烬数据做一些我认为应该相当简单的事情,但我到目前为止还没有任何运气 基本上,我想使用服务器数据填充一个
下拉菜单。提交表单时,应根据用户选择的数据创建模型。然后,模型与余烬数据一起保存,并以以下格式转发到服务器:
{
"File": {
"fileName":"the_name.txt",
"filePath":"/the/path",
"typeId": 13,
"versionId": 2
}
}
问题是,当模型关系定义为async时,typeId和versionId被忽略,如下所示:
App.File = DS.Model.extend({
type: DS.belongsTo('type', {async: true}),
version: DS.belongsTo('version', {async: true}),
fileName: DS.attr('string'),
filePath: DS.attr('string')
});
让我困惑的部分,可能是我的错误所在,是控制器:
App.FilesNewController = Ember.ObjectController.extend({
needs: ['files'],
uploadError: false,
// These properties will be given by the binding in the view to the
//<select> inputs.
selectedType: null,
selectedVersion: null,
files: Ember.computed.alias('controllers.files'),
actions: {
createFile: function() {
this.createFileHelper();
}
},
createFileHelper: function() {
var selectedType = this.get('selectedType');
var selectedVersion = this.get('selectedVersion');
var file = this.store.createRecord('file', {
fileName: 'the_name.txt',
filePath: '/the/path'
});
var gotDependencies = function(values) {
//////////////////////////////////////
// This only works when async: false
file.set('type', values[0])
.set('version', values[1]);
//////////////////////////////////////
var onSuccess = function() {
this.transitionToRoute('files');
}.bind(this);
var onFail = function() {
this.set('uploadError', true);
}.bind(this);
file.save().then(onSuccess, onFail);
}.bind(this);
Ember.RSVP.all([
selectedType,
selectedVersion
]).then(gotDependencies);
}
});
我意识到以前有人问过这个问题,但到目前为止我还没有找到满意的答案,也没有找到任何适合我需要的答案。那么,如何正确序列化belongsTo关系?
为了确保所有内容都在这里,我将添加到目前为止的自定义序列化:
App.ApplicationSerializer = DS.RESTSerializer.extend({
serializeIntoHash: function(data, type, record, options) {
var root = Ember.String.capitalize(type.typeKey);
data[root] = this.serialize(record, options);
},
keyForRelationship: function(key, type){
if (type === 'belongsTo') {
key += "Id";
}
if (type === 'hasMany') {
key += "Ids";
}
return key;
}
});
App.FileSerializer = App.ApplicationSerializer.extend(DS.EmbeddedRecordsMixin, {
attrs: {
type: { serialize: 'id' },
version: { serialize: 'id' }
}
});
以及选择:
{{ view Ember.Select
contentBinding="controller.files.versions"
optionValuePath="content"
optionLabelPath="content.versionStr"
valueBinding="controller.selectedVersion"
id="selectVersion"
classNames="form-control"
prompt="-- Select Version --"}}
如有必要,我将附加其他路由和控制器(FileRoute、FileController、VersionRoute、TypesRoute)
编辑14年11月16日
我有一个基于两个相关线程中的信息找到的工作解决方案(hack?):
(一)
(二)
基本上,我所要做的就是将Ember.RSVP.all()
移动到属性上的get()
之后:
createFileHelper: function() {
var selectedType = this.get('selectedType');
var selectedVersion = this.get('selectedVersion');
var file = this.store.createRecord('file', {
fileName: 'the_name.txt',
filePath: '/the/path',
type: null,
version: null
});
file.set('type', values[0])
.set('version', values[1]);
Ember.RSVP.all([
file.get('type'),
file.get('version')
]).then(function(values) {
var onSuccess = function() {
this.transitionToRoute('files');
}.bind(this);
var onFail = function() {
alert("failure");
this.set('uploadError', true);
}.bind(this);
file.save().then(onSuccess, onFail);
}.bind(this));
}
因此,在保存模型之前,我需要
get()
属于关系的属性。我不知道这是不是一个错误。也许有人对emberjs有更多的了解,可以帮助我们了解这一点。有关更多细节,请参见问题,但我在使用belongsTo关系保存模型时(您特别需要序列化该关系)的一般回答是,在属性上调用.get()
,然后调用save()
将它们放入然后()
归结起来就是:
var file = this.store.createRecord('file', {
fileName: 'the_name.txt',
filePath: '/the/path',
type: null,
version: null
});
// belongsTo set() here
file.set('type', selectedType)
.set('version', selectedVersion);
Ember.RSVP.all([
file.get('type'),
file.get('version')
]).then(function(values) {
var onSuccess = function() {
this.transitionToRoute('files');
}.bind(this);
var onFail = function() {
alert("failure");
this.set('uploadError', true);
}.bind(this);
// Save inside then() after I call get() on promises
file.save().then(onSuccess, onFail);
}.bind(this));
我也遇到了同样的问题。有任何更新吗?@torazaburo您是否.get()
在请求承诺之前对属性进行了更新?i、 e.设置()
它们,然后在.get()
上使用.all()
或.then()
。看看我的答案。是的,我正在做set
然后get(…)。然后(…)
,它开始工作了,但这似乎被严重破坏了,我想知道你是否能想出更“优雅”的东西,在某种程度上,余烬中的任何东西都是优雅的。实际上,我不是在做一个单独的集合
,而是将散列中的值传递给createRecord
。
var file = this.store.createRecord('file', {
fileName: 'the_name.txt',
filePath: '/the/path',
type: null,
version: null
});
// belongsTo set() here
file.set('type', selectedType)
.set('version', selectedVersion);
Ember.RSVP.all([
file.get('type'),
file.get('version')
]).then(function(values) {
var onSuccess = function() {
this.transitionToRoute('files');
}.bind(this);
var onFail = function() {
alert("failure");
this.set('uploadError', true);
}.bind(this);
// Save inside then() after I call get() on promises
file.save().then(onSuccess, onFail);
}.bind(this));