From 8046c48cc2fe6645a50c41bdfeaa756e12931cd9 Mon Sep 17 00:00:00 2001 From: Aaron Sikes Date: Tue, 10 May 2016 11:32:34 -0400 Subject: [PATCH] [BUGFIX beta] Fix resetting of properties to in-flight values Changing the value of an in-flight property, then changing back, had the side effect that the record would be marked dirty once the save completed. `changedAttributes` would report that `name` had been changed from 'Thomas' to 'Thomas' This is because the attr computed was only checking to see if the value was being reset to the canonical value, not if it was being reset to the in-flight value --- addon/attr.js | 9 +++++++- tests/unit/model-test.js | 45 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/addon/attr.js b/addon/attr.js index 673fb7ee429..8ea5e864c56 100644 --- a/addon/attr.js +++ b/addon/attr.js @@ -140,16 +140,23 @@ export default function attr(type, options) { set(key, value) { var internalModel = this._internalModel; var oldValue = getValue(internalModel, key); + var originalValue; if (value !== oldValue) { // Add the new value to the changed attributes hash; it will get deleted by // the 'didSetProperty' handler if it is no different from the original value internalModel._attributes[key] = value; + if (key in internalModel._inFlightAttributes) { + originalValue = internalModel._inFlightAttributes[key] + } else { + originalValue = internalModel._data[key] + } + this._internalModel.send('didSetProperty', { name: key, oldValue: oldValue, - originalValue: internalModel._data[key], + originalValue: originalValue, value: value }); } diff --git a/tests/unit/model-test.js b/tests/unit/model-test.js index 67ed420f3ba..0d5d38f0477 100644 --- a/tests/unit/model-test.js +++ b/tests/unit/model-test.js @@ -97,6 +97,51 @@ test("resetting a property on a record cause it to become clean again", function }); }); +test("resetting a property to the current in-flight value causes it to become clean when the save completes", function(assert) { + assert.expect(4); + + var person, finishSaving; + + env.adapter.updateRecord = function(store, type, snapshot) { + // Make sure the save is async + return new Ember.RSVP.Promise(function(resolve, reject) { + finishSaving = resolve; + }); + }; + + run(function() { + store.push({ + data: { + type: 'person', + id: '1', + attributes: { + name: 'Tom' + } + } + }); + person = store.peekRecord('person', 1); + person.set('name', "Thomas"); + + person.save(); + }); + + run(function() { + assert.equal(person.get('name'), "Thomas"); + + person.set('name', 'Tomathy'); + assert.equal(person.get('name'), "Tomathy"); + + person.set('name', 'Thomas'); + assert.equal(person.get('name'), "Thomas"); + + finishSaving(); + }); + + run(function() { + assert.equal(person.get('hasDirtyAttributes'), false, "The person is now clean"); + }); +}); + test("a record becomes clean again only if all changed properties are reset", function(assert) { assert.expect(5); env.adapter.shouldBackgroundReloadRecord = () => false;