我正在尝试在更新后保存Ember数据DS.Model
,但当我致电myModel.save()
时,我发现Ember Data正在发送原始的,未更新的模型,而不是更新的模型。我试图理解为什么会发生这种情况以及我需要做些什么。
以下是一些细节。首先,我有两个模型:
/models/OrgUser.js:
DS.Model.extend({
...
orgPerson: DS.belongsTo('org-person', { inverse: 'org-user', async: true, embedded: 'always' }),
});
请注意,我使用的是自定义的RESTSerializer
(见下文),因此embedded: 'always'
的唯一用途是我的自定义RESTSerializer
如何处理它。
/models/OrgPerson.js:
DS.Model.extend({
...
orgUser: DS.belongsTo('org-user'),
})
要保留这些模型,请使用RESTAdapter
。为了尝试向包含上述两种模型的API生成单个JSON请求,我已对适配器进行了一次自定义。我不认为这会影响任何事情,但为了防止我错过了什么,这里是:
/serializers/application.js:
DS.RESTSerializer.extend({
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].get('data') : null;
}
else {
json[key] = data[relationship.key] ? data[relationship.key].get('id') : null;
}
if (relationship.options.polymorphic) {
this.serializePolymorphicType(record, json, relationship);
}
}
})
使用该设置,我有一个模板,我更新orgPerson属性。我可以确认这些是绑定属性,因为更新它们的输入会实时更新它们在模板的另一部分上的显示。然后我在我的控制器上调用action
,并在该操作中执行以下操作:
/controllers/my-page.js:
export default Ember.ObjectController.extend( FormMixin, {
actions: {
submitForm: function() {
...
this.get('model') // Chrome console shows that _data.orgPerson._data.firstName has the (incorrect) old property
this.get('model').serialize() // returns (incorrect) old firstName
this.get('orgPerson.firstName') // returns (correct) updated firstName
this.get('orgPerson').get('firstName') // returns (correct) updated firstName
...
}
}
});
我知道为什么我会得到同一型号的两个不同版本?如何序列化正确更新的模型?感谢您的任何意见!
SOLUTION:
再次感谢@ kingpin2k,我已经解决了这个问题。以下是我采取的步骤:
data[relationship.key].get('data')
替换为行data[relationship.key].serialize()
,这是固定的。model
以仅显示最新内容,但似乎没有任何Ember工具。orgPerson
是async: true
,我必须将我的模型包装在一个承诺中。另请注意,我必须直接致电model.orgPerson
而不是model
。 更新路线:
actions: {
willTransition: function( transition ) {
this.controller.get('model.orgPerson').then( function( value ) {
if ( value.get('isDirty') ) {
value.rollback();
}
});
}
}
this.controller.get('model').rollback()
,所以我要写一个遍历eachRelationship
的util函数,然后在任何一个对象上单独调用rollback()
。哇,这很有道理,让这个工作正常。答案 0 :(得分:2)
Ember Data将原始值存储在data
obj中。它将修改后的值存储在_attributes
obj中。在保存期间,它将_attributes
obj移动到inFlightAttributes
obj,然后在保存完成后将它们从inFlightAttributes
合并到data
。所有这些都是你可以回滚你的记录。
当您将某个属性定义为attr
时,它会将首先检查_attributes
,然后inFlightAttributes
,然后data
的魔法获取连接起来并返回该属性'结果。
function getValue(record, key) {
if (record._attributes.hasOwnProperty(key)) {
return record._attributes[key];
} else if (record._inFlightAttributes.hasOwnProperty(key)) {
return record._inFlightAttributes[key];
} else {
return record._data[key];
}
}
在您的情况下,Ember Data不知道您正在保存该记录,而您是从data
obj手动抓取旧属性。您需要手动将_attributes
合并到data
或欺骗Ember数据,以为您已将其保存。