Using ng-init
is the most robust method, if done right:
<div ng-repeat = "outerItem in outerObject"
ng-init = "outerIndex=$index">
<div ng-repeat = "innerItem in innerObject"
ng-click = "expression($index, outerIndex)"></div>
<div>
Here ng-init
grabs the value of $index
on the outer scope created by the outer ng-repeat
directive.
The same way you can use ng-init
to grab any value on the correct scope.
So the other answer putting ng-init
next to the second ng-repeat
would grab the index of that second repeater, not the outer one!
The usual scope inheritance caveaut applies - any other expression defining outerIndex
on a child scope will not change the one of the parent scope. Use object property such as outer.Index
instead, to avoid this effect.
This approach is also more robust as it will survive under code changes affecting $parent
scopes, e.g. by wrapping the interior repeater into any directive affecting scope hierarchy (such as ng-repeat
).
It is also easy to test (which e.g. any code using $parent
isn't).
Note that Angular official documentation for ng-init
considers this to be "the only appropriate use of it":
The only appropriate use of ngInit is for aliasing special properties of ngRepeat, as seen in the demo below. Besides this case, you should use controllers rather than ngInit
to initialize
values on a scope.