diff --git a/src/ng/directive/ngRepeat.js b/src/ng/directive/ngRepeat.js index 50be2a618e68..ac0bad2db9ec 100644 --- a/src/ng/directive/ngRepeat.js +++ b/src/ng/directive/ngRepeat.js @@ -218,7 +218,8 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) { return function($scope, $element, $attr){ var expression = $attr.ngRepeat; var match = expression.match(/^\s*(.+)\s+in\s+(.*?)\s*(\s+track\s+by\s+(.+)\s*)?$/), - trackByExp, trackByExpGetter, trackByIdFn, trackByIdArrayFn, trackByIdObjFn, lhs, rhs, valueIdentifier, keyIdentifier, + trackByExp, trackByExpGetter, trackByIdExpFn, trackByIdArrayFn, trackByIdObjFn, + lhs, rhs, valueIdentifier, keyIdentifier, hashFnLocals = {$id: hashKey}; if (!match) { @@ -232,7 +233,7 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) { if (trackByExp) { trackByExpGetter = $parse(trackByExp); - trackByIdFn = function(key, value, index) { + trackByIdExpFn = function(key, value, index) { // assign key, value, and $index to the locals so that they can be used in hash functions if (keyIdentifier) hashFnLocals[keyIdentifier] = key; hashFnLocals[valueIdentifier] = value; @@ -275,6 +276,7 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) { childScope, key, value, // key/value of iteration trackById, + trackByIdFn, collectionKeys, block, // last object information {scope, element, id} nextBlockOrder = []; @@ -282,9 +284,9 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) { if (isArrayLike(collection)) { collectionKeys = collection; - trackByIdFn = trackByIdFn || trackByIdArrayFn; + trackByIdFn = trackByIdArrayFn || trackByIdExpFn; } else { - trackByIdFn = trackByIdFn || trackByIdObjFn; + trackByIdFn = trackByIdObjFn || trackByIdExpFn; // if object, extract keys, sort them and use to determine order of iteration over obj props collectionKeys = []; for (key in collection) { diff --git a/test/ng/directive/ngRepeatSpec.js b/test/ng/directive/ngRepeatSpec.js index fc41bc6d71eb..720355666458 100644 --- a/test/ng/directive/ngRepeatSpec.js +++ b/test/ng/directive/ngRepeatSpec.js @@ -841,6 +841,26 @@ describe('ngRepeat', function() { expect(newLis[1]).toEqual(lis[0]); expect(newLis[2]).toEqual(lis[1]); }); + + it('should be stable even if the collection is initially undefined', function () { + scope.items = undefined; + scope.$digest(); + + scope.items = [ + { name: 'A' }, + { name: 'B' }, + { name: 'C' } + ]; + scope.$digest(); + + lis = element.find('li'); + scope.items.shift(); + scope.$digest(); + + var newLis = element.find('li'); + expect(newLis.length).toBe(2); + expect(newLis[0]).toBe(lis[1]); + }); }); it('should grow multi-node repeater', inject(function($compile, $rootScope) { @@ -861,8 +881,6 @@ describe('ngRepeat', function() { $rootScope.$digest(); expect(element.text()).toEqual('T1:D1;T2:D2;T3:D3;'); })); - - }); describe('ngRepeat animations', function() {