sproutcore/sproutcore — pull request #1153 by mirion (2013-12-19 01:45:08+00:00)
Title: Fix the content change notofications for array controller using orderBy.

If the array controller is sorted (via an orderBy) and new items are added, the ordered sequence may change so we need to trigger a notification for a full UI refresh. If only removing items (added == 0), the order of remaining elements is not changing therefore no need to perform such a full refresh. Of course, we could calculate the changes and notify only the modified rows but this would need much bigger changes into SC.ArrayController that may be more expensive than a simple refresh.

The best way to reproduce this bug is to use a list view and check the content of the 1st item before and after adding a new object to the array controller. I created a simple test case for this scenario but since it uses SC.ListView it can't be part of core_foundation (as ArrayController). On the other hand, putting it into desktop would not be correct either. It is included below so if necessary it can be inserted into the right place.

```
// ==========================================================================
// Project: SproutCore - JavaScript Application Framework
// Copyright: ©2006-2011 Strobe Inc. and contributors.
// Portions ©2008-2011 Apple Inc. All rights reserved.
// License: Licensed under MIT license (see license.js)
// ==========================================================================

/*globals throws should_throw*/
var content, controller, extra, list, pane;

var TestObject = SC.Object.extend({
value: null,
toString: function() { return "TestObject(%@)".fmt(this.get("value")); }
});

// ..........................................................
// NULL VALUE
//

module("SC.ArrayController - order_by", {
setup: function() {
SC.run(function () {
content = [ TestObject.create( { value: 1 } ), TestObject.create( { value: 2 } ) ];
controller = SC.ArrayController.create({
content: content,
orderBy: "value ASC"
});
extra = TestObject.create({ value: 0 });
list = SC.ListView.create({
layout: { width: 200, height: 400 },
content: controller.get( "arrangedObjects" )
});

pane = SC.Pane.create({
layout: { width: 200, height: 400 }
});
pane.appendChild(list);
pane.append();
});
},

teardown: function() {
pane.remove();
pane.destroy();
controller.destroy();
}
});

test("list_view_updated_correctly", function() {
equals( list.get( "childViews" ).objectAt( 0 ).get( "content" ).get( "value" ), 1, "the list should be properly initialized" );
SC.RunLoop.begin();
controller.get( "content" ).pushObject( extra );
SC.RunLoop.end();
equals( list.get( "childViews" ).objectAt( 0 ).get( "content" ).get( "value" ), 0, "the newly added object should be inserted as first item into the list" );
});

```