1

我正在尝试手动将脏记录发送到清洁状态(与如何使用 ember-data 手动将对象状态设置为清洁(保存)有关)。

我偶然发现了由于不希望使用 ember-data 或错误而可能发生的事情。

基本上,我所做的是

  1. 找到有问题的记录,
  2. .set()记录在案的财产,以及
  3. 手动将记录发送到“becameClean”状态。这样做是为了避免在调用App.store.commit();上述问题中提到的原因时提交记录。

在开始之前,我在 ember-data 部分添加了enter: function() { console.log(this); console.log(this.get('path')); }一行DS.State = ...,以便查看记录经历了哪些状态。

我正在运行 GitHub 的最新版本。这是我的方法:

步骤 1)致电App.Fruit.find('banana');

  • console.log(this);结果是:

    <DS.State:ember1077> { initialState="saved", isLoaded=true, saved=<DS.State:ember1078>, more...}

  • console.log(this.get('path'));结果是:

    1. 'rootState.empty'
    2. 'rootState.loading'
    3. 'rootState.loaded'
    4. 'rootState.loaded.saved'

步骤 2)致电App.Fruit.find('banana').set('description', 'Yellow fruit!');

  • console.log(this);结果是:

    <(subclass of DS.State):ember1084> { dirtyType="updated", childStates=[3], eventTransitions={...}, more...}

  • console.log(this.get('path'));结果是:

    1. 'rootState.loaded.updated'

步骤 3)致电App.store.get('defaultTransaction.buckets');

  • 导致记录出现在“更新”存储桶中

步骤 4)致电App.Fruit.find('banana').get('stateManager').send('becameClean');

  • console.log(this);结果是:

    <DS.State:ember1078> { childStates=[0], eventTransitions={...}, states={...}, more...}

  • console.log(this.get('path'));结果是:

    1. 'rootState.loaded.saved'

步骤 5)致电App.store.get('defaultTransaction.buckets');

  • 导致记录出现在“干净”存储桶中

中场休息:好的,到目前为止,一切都很好。看来我已成功将记录发送到干净状态。但是,会发生这种情况:

步骤 6)致电App.Fruit.find('banana').set('description', 'Even more yellow fruit!');

  • console.log(this);结果是:

    (没有)

  • console.log(this.get('path'));结果是:

    (没有)

步骤 7)致电App.store.get('defaultTransaction.buckets');

  • 导致记录出现在“干净”存储桶中

问题是,在我将“becameClean”状态发送到记录后,无论我之后是否更改记录,它都保持在“loaded.saved”状态。

当第 2 步导致使用 aDS.State创建新的子类对象时dirtyType="updated",为什么第 6 步也不会导致这种情况?

我的问题是:这是一个错误还是因为我不希望使用而不起作用.send('becameClean')

4

1 回答 1

1

简短的回答

这是因为手动触发记录的状态管理器上的任何事件,正如您所说的,“不可取”。这样一来,您就错过了记录完成的所有其他簿记。

从服务器注入这些新值的唯一安全方法是使用store.load(). (如果您真的想知道原因,请参阅下面的所有血腥细节。)这将确保进行正确的簿记。

不幸的是,这意味着您需要确保在侧载后安全地隐藏并重新应用任何未提交的更改(因为侧载将替换记录中的所有属性)。

长答案

在这种情况下,手动将记录标记为干净会在内部破坏几件事:(1)记录的脏因素列表保持不变,以及(2)记录的原始属性副本保持不变。

(1)脏因素是自上次提交以来发生变化的那些属性——属性和关联。记录使用此列表来决定记录是否需要转换为脏状态。当您设置一个属性(例如描述)时,它会检查其脏因子列表以查看该属性是否已被修改。如果没有,并且如果记录当前被认为是“干净的”,它会将记录转换为脏状态。

在您的示例中,您修改了描述,然后手动将记录标记为干净。然而,记录仍然认为它的描述是脏的,所以当你第二次去改变它时,它从来没有费心去转换到脏状态——它认为它已经在那里了。

(2)从技术上讲,您可以使用record.removeDirtyFactors()刷新脏因子并将记录转换为干净状态,但即使您这样做了,记录的原始属性副本仍然是错误的。当它实际上是“B”时,它会认为服务器有“A”。如果您随后尝试在客户端将其更改回“A”并提交,则该记录不会做任何事情——它会认为它已经与服务器重新同步。

于 2012-11-17T22:53:23.160 回答