diff --git a/packages/ember-model/lib/has_many.js b/packages/ember-model/lib/has_many.js index 998809e..4715611 100644 --- a/packages/ember-model/lib/has_many.js +++ b/packages/ember-model/lib/has_many.js @@ -46,6 +46,7 @@ Ember.Model.reopen({ modelClass: type, content: this._getHasManyContent(key, type, embedded), embedded: embedded, + ordered: !!meta.options.ordered, key: key, relationshipKey: meta.relationshipKey, container: container diff --git a/packages/ember-model/lib/has_many_array.js b/packages/ember-model/lib/has_many_array.js index 9ffefcc..39c3e94 100644 --- a/packages/ember-model/lib/has_many_array.js +++ b/packages/ember-model/lib/has_many_array.js @@ -17,22 +17,23 @@ Ember.ManyArray = Ember.RecordArray.extend({ var originalContent = get(this, 'originalContent'), originalContentLength = get(originalContent, 'length'), content = get(this, 'content'), - contentLength = get(content, 'length'); + contentLength = get(content, 'length'), + i, l; if (originalContentLength !== contentLength) { return true; } if (this._modifiedRecords && this._modifiedRecords.length) { return true; } - var isDirty = false; - - for (var i = 0, l = contentLength; i < l; i++) { - if (!originalContent.contains(content[i])) { - isDirty = true; - break; - } + if (get(this, 'ordered')) { + for (i = 0, l = contentLength; i < l; i++) { + if (originalContent.objectAt(i) !== content.objectAt(i)) { return true; } + } + } else { + for (i = 0, l = contentLength; i < l; i++) { + if (!originalContent.contains(content[i])) { return true; } + } } - - return isDirty; + return false; }.property('content.[]', 'originalContent.[]', '_modifiedRecords.[]'), objectAtContent: function(idx) { diff --git a/packages/ember-model/tests/has_many/manipulation_test.js b/packages/ember-model/tests/has_many/manipulation_test.js index 51e6339..cfacde0 100644 --- a/packages/ember-model/tests/has_many/manipulation_test.js +++ b/packages/ember-model/tests/has_many/manipulation_test.js @@ -283,4 +283,60 @@ test("setting a hasMany array with setObjects", function() { equal(article.get('comments.length'), 3, "should be 3 comments after revert"); equal(article.get('comments.isDirty'), false, "should not be dirty after revert"); -}); \ No newline at end of file +}); + +test("reordering a hasMany array", function () { + var json = { + id: 1, + title: 'foo', + comments: [1, 2, 3] + }; + + var Comment = Ember.Model.extend({ + text: attr() + }); + + var Article = Ember.Model.extend({ + title: attr(), + comments: Ember.hasMany(Comment, { key: 'comments', ordered: true }) + }); + + Comment.adapter = Ember.FixtureAdapter.create(); + Comment.FIXTURES = [ + {id: 1, text: 'uno'}, + {id: 2, text: 'dos'}, + {id: 3, text: 'tres'} + ]; + + var article = Article.create(); + Ember.run(article, article.load, json.id, json); + // New by default for some reason + article.get('comments').forEach(function (comment) { comment.set('isNew', false); }); + + // Control test + article.get('comments').setObjects([Comment.find(2), Comment.find(1), Comment.find(3)]); + equal(article.get('comments.length'), 3, "should be 3 comments after set"); + equal(article.get('comments.isDirty'), true, "comments should be dirty after set"); + + // Reorder using replace (through insertAt) + article.get('comments').removeAt(0); + article.get('comments').insertAt(1, Comment.find(2)); + equal(article.get('comments.length'), 3, "should be 3 comments after set"); + equal(article.get('comments.isDirty'), false, "should not be dirty after replacing to right order"); + + // Reorder using setObjects + article.get('comments').setObjects([Comment.find(2), Comment.find(1), Comment.find(3)]); + equal(article.get('comments.isDirty'), true, "comments should be dirty after set"); + + article.get('comments').setObjects([Comment.find(1), Comment.find(2), Comment.find(3)]); + equal(article.get('comments.length'), 3, "should be 3 comments after set"); + equal(article.get('comments.isDirty'), false, "should not be dirty after setObjects in right order"); + + // Reorder using item array + article.get('comments').setObjects([Comment.find(2), Comment.find(1), Comment.find(3)]); + equal(article.get('comments.isDirty'), true, "comments should be dirty after set"); + + article.set('comments', [Comment.find(1), Comment.find(2), Comment.find(3)]); + equal(article.get('comments.length'), 3, "should be 3 comments after set"); + equal(article.get('comments.isDirty'), false, "should not be dirty after set in right order"); +});