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

Commit d71d689

Browse files
committedOct 14, 2014
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 d71d689

File tree

2 files changed

+48
-8
lines changed

2 files changed

+48
-8
lines changed
 

‎src/ng/directive/ngRepeat.js

+11-8
Original file line numberDiff line numberDiff line change
@@ -211,18 +211,21 @@
211211
var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) {
212212
var NG_REMOVED = '$$NG_REMOVED';
213213
var ngRepeatMinErr = minErr('ngRepeat');
214+
var nullAliasProperties = {};
214215

215-
var updateScope = function(scope, index, valueIdentifier, value, keyIdentifier, key, arrayLength) {
216+
var updateScope = function(scope, index, valueIdentifier, value, keyIdentifier, key, arrayLength, aliasAs) {
217+
var aliasRef = aliasAs ? {} : nullAliasProperties;
216218
// TODO(perf): generate setters to shave off ~40ms or 1-1.5%
217219
scope[valueIdentifier] = value;
218220
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);
221+
aliasRef.$index = scope.$index = index;
222+
aliasRef.$first = scope.$first = (index === 0);
223+
aliasRef.$last = scope.$last = (index === (arrayLength - 1));
224+
aliasRef.$middle = scope.$middle = !(scope.$first || scope.$last);
223225
// jshint bitwise: false
224-
scope.$odd = !(scope.$even = (index&1) === 0);
226+
aliasRef.$odd = scope.$odd = !(aliasRef.$even = scope.$even = (index&1) === 0);
225227
// jshint bitwise: true
228+
if (aliasAs) scope['$' + aliasAs] = aliasRef;
226229
};
227230

228231
var getBlockStart = function(block) {
@@ -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);
415418
} else {
416419
// new item which we don't know about
417420
$transclude(function ngRepeatTransclude(clone, scope) {
@@ -428,7 +431,7 @@ 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);
432435
});
433436
}
434437
}

‎test/ng/directive/ngRepeatSpec.js

+37
Original file line numberDiff line numberDiff line change
@@ -492,6 +492,43 @@ describe('ngRepeat', function() {
492492
return text.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
493493
}
494494
}));
495+
496+
it('should expose the index properties using `${{userSpecifiedAliasName}}`', 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+
}));
522+
523+
it('should be possible to access the alias inside the loop', inject(function() {
524+
element = $compile(
525+
'<div>' +
526+
' <div ng-repeat="item in items as results">{{results[$index]}}</div>' +
527+
'</div>')(scope);
528+
scope.items = ['a','b','c','d','e','f'];
529+
scope.$digest();
530+
expect(trim(element.text())).toEqual('abcdef');
531+
}));
495532
});
496533

497534

0 commit comments

Comments
 (0)