Sunday 3 May 2015

Use ngInit to Track $index in Nested ngRepeats

Recently some colleagues of mine were trying to do some conditional logic on an input element buried away in a couple of ngRepeats based on the index of the first ngRepeat. They were getting into a pickle using $scope.$parent.$parent.$index. When they were printing out the $index it was giving them the answer they wanted, but then didn't behave in the same way when used within their logic on the input element. It turned out that this input was one $parent further away and they querying the wrong scope. This is the time to use ngInit.

Syntax

In order to avoid confusing and messy chains of $parent, set the $index of the current iteration through the ngRepeat to a variable. In the example below I've assigned $index on each ngRepeat to different variables and then in the heart of them all I've printed them out.

<div ng-repeat="object in vm.objects" ng-init="objectIndex = $index">
    <div ng-repeat="box in object" ng-init="boxIndex = $index">
        <div ng-repeat="toy in box">
            <p>Toy Index: {{$index}}, Box Index: {{boxIndex}}, Object Index: {{objectIndex}}</p>
        </div>
    </div>
</div>


The output is something like this:

Toy Index: 0, Box Index: 0, Object Index: 0
Toy Index: 1, Box Index: 0, Object Index: 0
Toy Index: 2, Box Index: 0, Object Index: 0
Toy Index: 3, Box Index: 0, Object Index: 0
Toy Index: 4, Box Index: 0, Object Index: 0
Toy Index: 0, Box Index: 1, Object Index: 0
Toy Index: 1, Box Index: 1, Object Index: 0
Toy Index: 2, Box Index: 1, Object Index: 0
Toy Index: 3, Box Index: 1, Object Index: 0
Toy Index: 4, Box Index: 1, Object Index: 0
Toy Index: 0, Box Index: 2, Object Index: 0
Toy Index: 1, Box Index: 2, Object Index: 0
Toy Index: 2, Box Index: 2, Object Index: 0
Toy Index: 3, Box Index: 2, Object Index: 0
Toy Index: 4, Box Index: 2, Object Index: 0
Toy Index: 0, Box Index: 3, Object Index: 0
Toy Index: 1, Box Index: 3, Object Index: 0
Toy Index: 2, Box Index: 3, Object Index: 0
Toy Index: 3, Box Index: 3, Object Index: 0
Toy Index: 4, Box Index: 3, Object Index: 0
Toy Index: 0, Box Index: 4, Object Index: 0
Toy Index: 1, Box Index: 4, Object Index: 0
Toy Index: 2, Box Index: 4, Object Index: 0
Toy Index: 3, Box Index: 4, Object Index: 0
Toy Index: 4, Box Index: 4, Object Index: 0

And so it goes on through all the objects, boxes, and toys.

According to the documentation ngInit should only be used with ngRepeat. I can't at this time think of any other use for ngInit, but this alone is more than good enough.

The code for this post can be found on GitHub.

No comments:

Post a Comment