diff options
| author | Pete Bacon Darwin | 2013-01-11 12:47:38 +0000 |
|---|---|---|
| committer | Igor Minar | 2013-01-17 00:25:07 -0800 |
| commit | ed2fd2d0caad4e4b45f79bb39fd2a8b03fea8faa (patch) | |
| tree | bee7ee236a01f009cc393d5147643c2d03ac3d44 | |
| parent | 7c60151cb8ca6ce8fc49846b7ae2f536d0d2cc28 (diff) | |
| download | angular.js-ed2fd2d0caad4e4b45f79bb39fd2a8b03fea8faa.tar.bz2 | |
fix(ngRepeat): correctly apply $last if repeating over object
If the $last property is calculated from the original collectionLength
on an object and properties starting with $ were filtered out, then $last
is never applied and $middle is applied erroniously.
Closes #1789
| -rw-r--r-- | src/ng/directive/ngRepeat.js | 15 | ||||
| -rw-r--r-- | test/ng/directive/ngRepeatSpec.js | 15 |
2 files changed, 25 insertions, 5 deletions
diff --git a/src/ng/directive/ngRepeat.js b/src/ng/directive/ngRepeat.js index 893ad442..c59fefac 100644 --- a/src/ng/directive/ngRepeat.js +++ b/src/ng/directive/ngRepeat.js @@ -92,14 +92,17 @@ var ngRepeatDirective = ngDirective({ scope.$watch(function ngRepeatWatch(scope){ var index, length, collection = scope.$eval(rhs), - collectionLength = size(collection, true), - childScope, + cursor = iterStartElement, // current position of the node // Same as lastOrder but it has the current state. It will become the // lastOrder on the next iteration. nextOrder = new HashQueueMap(), + arrayLength, + childScope, key, value, // key/value of iteration - array, last, // last object information {scope, element, index} - cursor = iterStartElement; // current position of the node + array, + last; // last object information {scope, element, index} + + if (!isArray(collection)) { // if object, extract keys, sort them and use to determine order of iteration over obj props @@ -114,6 +117,8 @@ var ngRepeatDirective = ngDirective({ array = collection || []; } + arrayLength = array.length; + // we are not using forEach for perf reasons (trying to avoid #call) for (index = 0, length = array.length; index < length; index++) { key = (collection === array) ? index : array[index]; @@ -149,7 +154,7 @@ var ngRepeatDirective = ngDirective({ childScope.$index = index; childScope.$first = (index === 0); - childScope.$last = (index === (collectionLength - 1)); + childScope.$last = (index === (arrayLength - 1)); childScope.$middle = !(childScope.$first || childScope.$last); if (!last) { diff --git a/test/ng/directive/ngRepeatSpec.js b/test/ng/directive/ngRepeatSpec.js index a45cd972..33e4dcfd 100644 --- a/test/ng/directive/ngRepeatSpec.js +++ b/test/ng/directive/ngRepeatSpec.js @@ -293,6 +293,21 @@ describe('ngRepeat', function() { }); + it('should calculate $first, $middle and $last when we filter out properties from an obj', function() { + element = $compile( + '<ul>' + + '<li ng-repeat="(key, val) in items">{{key}}:{{val}}:{{$first}}-{{$middle}}-{{$last}}|</li>' + + '</ul>')(scope); + scope.items = {'misko':'m', 'shyam':'s', 'doug':'d', 'frodo':'f', '$toBeFilteredOut': 'xxxx'}; + scope.$digest(); + expect(element.text()). + toEqual('doug:d:true-false-false|' + + 'frodo:f:false-true-false|' + + 'misko:m:false-true-false|' + + 'shyam:s:false-false-true|'); + }); + + it('should ignore $ and $$ properties', function() { element = $compile('<ul><li ng-repeat="i in items">{{i}}|</li></ul>')(scope); scope.items = ['a', 'b', 'c']; |
