Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit 27662bf

Browse files
committed
feat(ngRepeat): expose the iterating properties over the alias
Expose the properties `$index`, `$first`, `$middle`, `$last`, `$odd` and `$even` as part of the alias Closes #9582
1 parent 02aa4f4 commit 27662bf

File tree

2 files changed

+40
-8
lines changed

2 files changed

+40
-8
lines changed

src/ng/directive/ngRepeat.js

+13-8
Original file line numberDiff line numberDiff line change
@@ -212,17 +212,19 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) {
212212
var NG_REMOVED = '$$NG_REMOVED';
213213
var ngRepeatMinErr = minErr('ngRepeat');
214214

215-
var updateScope = function(scope, index, valueIdentifier, value, keyIdentifier, key, arrayLength) {
215+
var updateScope = function(scope, index, valueIdentifier, value, keyIdentifier, key, arrayLength, aliasAs, LocalAlias) {
216+
var aliasRef = aliasAs ? new LocalAlias() : {};
216217
// TODO(perf): generate setters to shave off ~40ms or 1-1.5%
217218
scope[valueIdentifier] = value;
218219
if (keyIdentifier) scope[keyIdentifier] = key;
219-
scope.$index = index;
220-
scope.$first = (index === 0);
221-
scope.$last = (index === (arrayLength - 1));
222-
scope.$middle = !(scope.$first || scope.$last);
220+
aliasRef.$index = scope.$index = index;
221+
aliasRef.$first = scope.$first = (index === 0);
222+
aliasRef.$last = scope.$last = (index === (arrayLength - 1));
223+
aliasRef.$middle = scope.$middle = !(scope.$first || scope.$last);
223224
// jshint bitwise: false
224-
scope.$odd = !(scope.$even = (index&1) === 0);
225+
aliasRef.$odd = scope.$odd = !(aliasRef.$even = scope.$even = (index&1) === 0);
225226
// jshint bitwise: true
227+
if (aliasAs) scope[aliasAs] = aliasRef;
226228
};
227229

228230
var getBlockStart = function(block) {
@@ -328,6 +330,7 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) {
328330

329331
if (aliasAs) {
330332
$scope[aliasAs] = collection;
333+
LocalAlias.prototype = collection;
331334
}
332335

333336
if (isArrayLike(collection)) {
@@ -411,7 +414,7 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) {
411414
$animate.move(getBlockNodes(block.clone), null, jqLite(previousNode));
412415
}
413416
previousNode = getBlockEnd(block);
414-
updateScope(block.scope, index, valueIdentifier, value, keyIdentifier, key, collectionLength);
417+
updateScope(block.scope, index, valueIdentifier, value, keyIdentifier, key, collectionLength, aliasAs, LocalAlias);
415418
} else {
416419
// new item which we don't know about
417420
$transclude(function ngRepeatTransclude(clone, scope) {
@@ -428,11 +431,13 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) {
428431
// by a directive with templateUrl when its template arrives.
429432
block.clone = clone;
430433
nextBlockMap[block.id] = block;
431-
updateScope(block.scope, index, valueIdentifier, value, keyIdentifier, key, collectionLength);
434+
updateScope(block.scope, index, valueIdentifier, value, keyIdentifier, key, collectionLength, aliasAs, LocalAlias);
432435
});
433436
}
434437
}
435438
lastBlockMap = nextBlockMap;
439+
440+
function LocalAlias() {}
436441
});
437442
};
438443
}

test/ng/directive/ngRepeatSpec.js

+27
Original file line numberDiff line numberDiff line change
@@ -492,6 +492,33 @@ describe('ngRepeat', function() {
492492
return text.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
493493
}
494494
}));
495+
496+
it('should expose the index properties in the alias', inject(function() {
497+
var expression = '{{item}}-{{results.' + ['$index', '$first', '$middle', '$last', '$odd', '$even'].join('}}-{{results.') + '}}:';
498+
element = $compile(
499+
'<div>' +
500+
' <div ng-repeat="item in items as results">' + expression + '</div>' +
501+
'</div>')(scope);
502+
503+
scope.items = ['a','b','c','d','e','f'];
504+
scope.$digest();
505+
expect(trim(element.text())).toEqual(
506+
'a-0-true-false-false-false-true:' +
507+
'b-1-false-true-false-true-false:' +
508+
'c-2-false-true-false-false-true:' +
509+
'd-3-false-true-false-true-false:' +
510+
'e-4-false-true-false-false-true:' +
511+
'f-5-false-false-true-true-false:');
512+
513+
scope.items.shift();
514+
scope.$digest();
515+
expect(trim(element.text())).toEqual(
516+
'b-0-true-false-false-false-true:' +
517+
'c-1-false-true-false-true-false:' +
518+
'd-2-false-true-false-false-true:' +
519+
'e-3-false-true-false-true-false:' +
520+
'f-4-false-false-true-false-true:');
521+
}));
495522
});
496523

497524

0 commit comments

Comments
 (0)