`DS.attr()` 中的嵌套对象不受 `DS.rollbackAttributes()` 影响 [英] Nested object in `DS.attr()` isn't affected by `DS.rollbackAttributes()`
问题描述
我有一个模型 User
如下:
I have a model User
as follow:
import DS from 'ember-data';
const { attr, Model } = DS;
export default Model.extend({
name: attr("string"),
properties: attr(),
});
User.properties
用于保存 JSON 对象.
User.properties
is intended to hold a JSON object.
我正在通过表单更新模型(使用 ember-one-way-controls) 如下:
I am updating the model through a form (using ember-one-way-controls) as follow:
{{one-way-textarea
model.name
update=(action (mut model.name))}}
{{one-way-textarea
model.properties.description
update=(action (mut model.properties.description))}}
我有一个按钮,允许用户通过调用 discardChanges
操作来放弃更改:
I have a button allowing the user to discard the changes by calling a discardChanges
action:
actions: {
discardChanges(model) {
model.rollbackAttributes();
},
},
name
属性更改正确丢弃/重置,但 properties
属性不是.
The name
attribute changes are correctly discard / reset but the properties
attribute is not.
我该如何处理?
推荐答案
问题根源
Ember Data 不知道这些更改,因为它使用 ===
运算符将脏的属性与原始属性进行比较.如果发现更改,Ember Data 将脏的属性键存储在 _attributes
数组中.我们在这里注意到这一点.您调用 DS.rollbackAttributes()
,模型会查看 _attributes
以确认要恢复的属性.在这里./a>
Ember Data isn't aware of the changes because it uses ===
operator to compare the dirtied attribute against the original one. If a change has been spotted, Ember Data stores the dirtied attribute key in the _attributes
array. 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 解释器的一个例子:
JS is all about value passed by reference. Here is an example from Node interpreter:
> var foo = { description: 'hello' }
undefined
> var bar = foo;
undefined
> bar.description = 'bonjour';
'bonjour'
> bar === foo
true
您正在修改原始对象.
解决方案
一种可能的解决方案是深度复制您的 properties
对象并在调用 discardChanges
时手动重置它.
A possible solution is to deep-copy your properties
object and manually reset it when calling discardChanges
.
您可以将其实现为服务:
You can implement it as a service :
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
. - You call
start
when you enter in edition mode. - You call
undo
when you want to discard the changes. - You call
finalize
when you successfully saved your record.
这篇关于`DS.attr()` 中的嵌套对象不受 `DS.rollbackAttributes()` 影响的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!