Skip to content

Commit

Permalink
[BUGFIX release] fix array observers and property notifications
Browse files Browse the repository at this point in the history
Closes #3498
  • Loading branch information
tchak committed Jul 18, 2015
1 parent 7221cdf commit 430019a
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 19 deletions.
39 changes: 20 additions & 19 deletions packages/ember-data/lib/system/model/errors.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
var get = Ember.get;
var set = Ember.set;
var isEmpty = Ember.isEmpty;
var makeArray = Ember.makeArray;

import {
MapWithDefault
Expand Down Expand Up @@ -91,7 +93,7 @@ import {
@uses Ember.Enumerable
@uses Ember.Evented
*/
export default Ember.Object.extend(Ember.Enumerable, Ember.Evented, {
export default Ember.ArrayProxy.extend(Ember.Evented, {
/**
Register with target handler
Expand Down Expand Up @@ -176,22 +178,13 @@ export default Ember.Object.extend(Ember.Enumerable, Ember.Evented, {
return errors;
},

/**
@method nextObject
@private
*/
nextObject: function(index, previousObject, context) {
return get(this, 'content').objectAt(index);
},

/**
Total number of errors.
@property length
@type {Number}
@readOnly
*/
length: Ember.computed.oneWay('content.length').readOnly(),

/**
@property isEmpty
Expand Down Expand Up @@ -220,11 +213,10 @@ export default Ember.Object.extend(Ember.Enumerable, Ember.Evented, {
var wasEmpty = get(this, 'isEmpty');

messages = this._findOrCreateMessages(attribute, messages);
get(this, 'content').addObjects(messages);
this.addObjects(messages);
get(this, 'errorsByAttributeName').get(attribute).addObjects(messages);

this.notifyPropertyChange(attribute);
this.enumerableContentDidChange();

if (wasEmpty && !get(this, 'isEmpty')) {
this.trigger('becameInvalid');
Expand All @@ -238,7 +230,7 @@ export default Ember.Object.extend(Ember.Enumerable, Ember.Evented, {
_findOrCreateMessages: function(attribute, messages) {
var errors = this.errorsFor(attribute);

return Ember.makeArray(messages).map((message) => {
return makeArray(messages).map((message) => {
return errors.findBy('message', message) || {
attribute: attribute,
message: message
Expand Down Expand Up @@ -283,12 +275,11 @@ export default Ember.Object.extend(Ember.Enumerable, Ember.Evented, {
remove: function(attribute) {
if (get(this, 'isEmpty')) { return; }

var content = get(this, 'content').rejectBy('attribute', attribute);
get(this, 'content').setObjects(content);
let content = this.rejectBy('attribute', attribute);
set(this, 'content', content);
get(this, 'errorsByAttributeName').delete(attribute);

this.notifyPropertyChange(attribute);
this.enumerableContentDidChange();

if (get(this, 'isEmpty')) {
this.trigger('becameValid');
Expand Down Expand Up @@ -319,9 +310,19 @@ export default Ember.Object.extend(Ember.Enumerable, Ember.Evented, {
clear: function() {
if (get(this, 'isEmpty')) { return; }

get(this, 'content').clear();
get(this, 'errorsByAttributeName').clear();
this.enumerableContentDidChange();
let errorsByAttributeName = get(this, 'errorsByAttributeName');
let attributes = Ember.A();

errorsByAttributeName.forEach(function(_, attribute) {
attributes.push(attribute);
});

errorsByAttributeName.clear();
attributes.forEach(function(attribute) {
this.notifyPropertyChange(attribute);
}, this);

this._super();

this.trigger('becameValid');
},
Expand Down
20 changes: 20 additions & 0 deletions packages/ember-data/tests/unit/model/rollback-attributes-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,7 @@ test("deleted record's attributes can be rollbacked", function() {
});

test("invalid record's attributes can be rollbacked", function() {
expect(10);
Dog = DS.Model.extend({
name: DS.attr()
});
Expand Down Expand Up @@ -263,17 +264,32 @@ test("invalid record's attributes can be rollbacked", function() {
});

run(function() {
Ember.addObserver(dog, 'errors.name', function() {
ok(true, 'errors.name did change');
});

dog.get('errors').addArrayObserver({}, {
willChange: function() {
ok(true, 'errors will change');
},
didChange: function() {
ok(true, 'errors did change');
}
});

dog.save().then(null, async(function() {
dog.rollbackAttributes();

equal(dog.get('hasDirtyAttributes'), false, "must not be dirty");
equal(dog.get('name'), "Pluto");
ok(Ember.isEmpty(dog.get('errors.name')));
ok(dog.get('isValid'));
}));
});
});

test("invalid record's attributes rolled back to correct state after set", function() {
expect(13);
Dog = DS.Model.extend({
name: DS.attr(),
breed: DS.attr()
Expand Down Expand Up @@ -311,6 +327,10 @@ test("invalid record's attributes rolled back to correct state after set", funct
});

run(function() {
Ember.addObserver(dog, 'errors.name', function() {
ok(true, 'errors.name did change');
});

dog.save().then(null, async(function() {
equal(dog.get('name'), "is a dwarf planet");
equal(dog.get('breed'), "planet");
Expand Down

0 comments on commit 430019a

Please sign in to comment.