Skip to content

Commit

Permalink
Update Wecc's property change notification pr based on pr feedback
Browse files Browse the repository at this point in the history
  • Loading branch information
bmac committed Jun 8, 2015
1 parent df8f14a commit cd43c95
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 7 deletions.
58 changes: 51 additions & 7 deletions packages/ember-data/lib/system/model/internal-model.js
Original file line number Diff line number Diff line change
Expand Up @@ -588,10 +588,9 @@ InternalModel.prototype = {
this.didCleanError();
var changedKeys = this._changedKeys(data);

merge(this._data, this._inFlightAttributes);
if (data) {
merge(this._data, data);
} else {
merge(this._data, this._inFlightAttributes);
}

this._inFlightAttributes = Ember.create(null);
Expand Down Expand Up @@ -664,27 +663,72 @@ InternalModel.prototype = {
this._inFlightAttributes = Ember.create(null);
},

/**
/**
@method _changedKeys
Ember Data has 3 buckets for storing the value of an attribute on an internalModel.
`_data` holds all of the attributes that have been acknowledged by
a backend via the adapter. When rollback is called on a model all
attributes will revert to the record's state in `_data`.
`_attributes` holds any change the user has made to an attribute
that has not been acknowledged by the adapter. Any values in
`_attributes` are have priority over values in `_data`.
`_inFlightAttributes`. When a record is being synced with the
backend the values in `_attributes` are copied to
`_inFlightAttributes`. This way if the backend acknowledges the
save but does not return the new state Ember Data can copy the
values from `_inFlightAttributes` to `_data`. Without having to
worry about changes made to `_attributes` while the save was
happenign.
Changed keys builds a list of all of the values that may have been
changed by the backend after a successful save.
It does this by iterating over each key, value pair in the payload
returned from the server after a save. If the `key` is found in
`_attributes` then the user has a local changed to the attribute
that has not been synced with the server and the key is not
included in the list of changed keys.
If the value, for a key differs from the value in what Ember Data
believes to be the truth about the backend state (A merger of the
`_data` and `_inFlightAttributes` objects where
`_inFlightAttributes` has priority) then that means the backend
has updated the value and the key is added to the list of changed
keys.
@private
*/
_changedKeys: function(updates) {
var changedKeys = [];

if (updates && typeof updates === 'object') {
if (updates) {
var original, i, value, key;
var keys = Ember.keys(updates);
var length = keys.length;

original = merge({}, this._data);
original = merge(original, this._attributes);
original = merge(Ember.create(null), this._data);
original = merge(original, this._inFlightAttributes);

for (i = 0; i < length; i++) {
key = keys[i];
value = updates[key];

if (original[key] !== value) {
// A value in _attributes means the user has a local change to
// this attributes. We never override this value when merging
// updates from the backend so we should not sent a change
// notification if the server value differs from the original.
if (this._attributes[key] !== undefined) {
continue;
}

if (!Ember.isEqual(original[key], value)) {
changedKeys.push(key);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,3 +113,34 @@ test('Saving a record trigger observers for locally changed attributes with the
person.save();
});
});

test('store.push should not override a modified attribute', function() {
expect(1);
var person;

run(function() {
person = store.push('person', {
id: 'wat',
firstName: 'Yehuda',
lastName: 'Katz'
});

person.set('lastName', 'Katz!');
});

person.addObserver('firstName', function() {
ok(true, 'firstName observer should be triggered');
});

person.addObserver('lastName', function() {
ok(false, 'lastName observer should not be triggered');
});

run(function() {
person = store.push('person', {
id: 'wat',
firstName: 'Tom',
lastName: 'Dale'
});
});
});

0 comments on commit cd43c95

Please sign in to comment.