sproutcore/sproutcore — pull request #763 by krotscheck (2012-04-05 19:12:21+00:00)
Title: SC.ChildArray multiple arrayContentWillChange fix.

We discovered a rather insidious little bug in how ChildArray handles changes. The first time a push was made, arrayContentWillChange/arrayContentDidChange would fire only once. The second time, however, it would fire twice. Most of the code is in the replace() method, and the order of operations went something like this:

First time:
- User replaces a record
- Children have the records replaced
- _performRecordPropertyChange would set up array listeners on the new children.
- ChildArray dispatches arrayContentWillChange and arrayContentDidChange

Second Time:
- User replaces a record
- Children have the records replaced
- Array listeners previously set up in first round fire and are rebroadcast.
- _performRecordPropertyChange sets up new event listeners
- ChildArray dispatches willChange and didChange a second time.

The fix is fairly straightforward: Set up the array listeners before modifying the children, and then let the already established array listeners handle everything else. This way ChildArray won't have broadcast its own events and only reacts to changes in its children.

Normally this isn't actually that bad a bug, however if you combine this with the TemplateCollectionView, which actually pays attention to (index,removedCount,addedCount) and only adds/removes the rows indicated, it can be destructive to have it react to a single array change, twice (as it would try to add/remove x rows, twice).