`DS.attr()` 中的嵌套对象不受 `DS.rollbackAttributes()` 影响 [英] Nested object in `DS.attr()` isn't affected by `DS.rollbackAttributes()`

查看:9
本文介绍了`DS.attr()` 中的嵌套对象不受 `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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆