`DS.attr()` 中的嵌套对象不受 `DS.rollbackAttributes()` 的影响
Nested object in `DS.attr()` isn't affected by `DS.rollbackAttributes()`
我有一个模型 User
如下:
import DS from 'ember-data';
const { attr, Model } = DS;
export default Model.extend({
name: attr("string"),
properties: attr(),
});
User.properties
旨在容纳一个 JSON 对象。
我正在通过如下形式(使用 ember-one-way-controls)更新模型:
{{one-way-textarea
model.name
update=(action (mut model.name))}}
{{one-way-textarea
model.properties.description
update=(action (mut model.properties.description))}}
我有一个按钮,允许用户通过调用 discardChanges
操作来放弃更改:
actions: {
discardChanges(model) {
model.rollbackAttributes();
},
},
name
属性更改被正确丢弃/重置,但 properties
属性不是。
我该如何处理?
问题的来源
Ember 数据不知道更改,因为它使用 ===
运算符将脏属性与原始属性进行比较。如果发现更改,Ember Data 会将脏属性键存储在 _attributes
数组中。 We notice this here. Then, when you call DS.rollbackAttributes()
, the model looks at the _attributes
to acknowledge the attributes to restore. Here it is.
但是哈希值不一样!
JS 是关于通过引用传递值的。这是来自 Node 解释器的示例:
> var foo = { description: 'hello' }
undefined
> var bar = foo;
undefined
> bar.description = 'bonjour';
'bonjour'
> bar === foo
true
您正在修改原始对象。
解决方案
一个可能的解决方案是深度复制您的 properties
对象并在调用 discardChanges
.
时手动重置它
您可以将其实现为服务:
import Ember from 'ember';
const { copy, Service } = Ember;
export default Service.extend({
savedProperties: null,
finalize() {
this.set('savedProperties', null);
},
start(model) {
const properties = copy(model.get('properties'));
this.set("savedProperties", properties);
},
undo(model) {
const savedProperties = this.get('savedProperties');
for (const property in savedProperties) {
if (savedProperties.hasOwnProperty(property)) {
const keyPath = `properties.${property}`;
model.set(keyPath, savedProperties[property]);
}
}
this.set('savedProperties', null);
},
});
- 进入编辑模式时调用
start
。
- 当您想放弃更改时调用
undo
。
- 当您成功保存您的记录时,您调用
finalize
。
我有一个模型 User
如下:
import DS from 'ember-data';
const { attr, Model } = DS;
export default Model.extend({
name: attr("string"),
properties: attr(),
});
User.properties
旨在容纳一个 JSON 对象。
我正在通过如下形式(使用 ember-one-way-controls)更新模型:
{{one-way-textarea
model.name
update=(action (mut model.name))}}
{{one-way-textarea
model.properties.description
update=(action (mut model.properties.description))}}
我有一个按钮,允许用户通过调用 discardChanges
操作来放弃更改:
actions: {
discardChanges(model) {
model.rollbackAttributes();
},
},
name
属性更改被正确丢弃/重置,但 properties
属性不是。
我该如何处理?
问题的来源
Ember 数据不知道更改,因为它使用 ===
运算符将脏属性与原始属性进行比较。如果发现更改,Ember Data 会将脏属性键存储在 _attributes
数组中。 We notice this here. Then, when you call DS.rollbackAttributes()
, the model looks at the _attributes
to acknowledge the attributes to restore. Here it is.
但是哈希值不一样!
JS 是关于通过引用传递值的。这是来自 Node 解释器的示例:
> var foo = { description: 'hello' }
undefined
> var bar = foo;
undefined
> bar.description = 'bonjour';
'bonjour'
> bar === foo
true
您正在修改原始对象。
解决方案
一个可能的解决方案是深度复制您的 properties
对象并在调用 discardChanges
.
您可以将其实现为服务:
import Ember from 'ember';
const { copy, Service } = Ember;
export default Service.extend({
savedProperties: null,
finalize() {
this.set('savedProperties', null);
},
start(model) {
const properties = copy(model.get('properties'));
this.set("savedProperties", properties);
},
undo(model) {
const savedProperties = this.get('savedProperties');
for (const property in savedProperties) {
if (savedProperties.hasOwnProperty(property)) {
const keyPath = `properties.${property}`;
model.set(keyPath, savedProperties[property]);
}
}
this.set('savedProperties', null);
},
});
- 进入编辑模式时调用
start
。 - 当您想放弃更改时调用
undo
。 - 当您成功保存您的记录时,您调用
finalize
。