Question

If I have nested ng-repeaters,, like this

<div ng-repeat="outeritem in outerobject">

    <div ng-repeat="inneritem in innerobject" ng-click="function(inneritem.key, $index)"></div>

<div>

How would I get the $index from outterobject repeater in function(inneritem.key, $index) which is in ng-click directive of innerobject repeater?

Update:

I ended up using this approach although there are two other good ones mentioned in below posts.

<div ng-repeat="(indexvalue, outeritem) in outerobject">

    <div ng-repeat="inneritem in innerobject" ng-click="function(inneritem.key, indexvalue)"></div>

<div>
Was it helpful?

Solution

You can use $parent to access the scope of parent element.

ng-click="function(inneritem.key, $parent.$index)"

OTHER TIPS

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.

You can also use ng-init and set it explicitly

<div ng-repeat="outeritem in outerobject">

    <div ng-init='outerindex=$index' ng-repeat="inneritem in innerobject" ng-click="function(inneritem.key, outerindex)"></div>

<div>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top