Skip to content

Commit

Permalink
fix(ngRepeat): correctly apply $last if repeating over object
Browse files Browse the repository at this point in the history
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.

Fixes angular#1789
  • Loading branch information
petebacondarwin authored and IgorMinar committed Jan 17, 2013
1 parent 25c8cb9 commit 9c6d22c
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 6 deletions.
15 changes: 10 additions & 5 deletions src/ng/directive/ngRepeat.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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];
Expand Down Expand Up @@ -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) {
Expand Down
17 changes: 16 additions & 1 deletion test/ng/directive/ngRepeatSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ describe('ngRepeat', function() {
'<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', '$internal': 'xxxx'};
scope.items = {'misko':'m', 'shyam':'s', 'doug':'d', 'frodo':'f'};
scope.$digest();
expect(element.text()).
toEqual('doug:d:true-false-false|' +
Expand All @@ -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'];
Expand Down

0 comments on commit 9c6d22c

Please sign in to comment.