$index of ngRepeat inside angularjs directive

DavidB picture DavidB · Jan 3, 2013 · Viewed 31.7k times · Source

I'm trying to find the best way to get an index position within an ngRepeat used with a custom directive. The problem I'm trying to solve is that for each iteration of the ngRepeat, I'd like the option of knowing where I am in the iteration so I can create a custom template based on that index position.

Unless there is a better way of doing this, I'm attempting to do this functionality based on this documentation from directives:

& or &attr - provides a way to execute an expression in the context of the parent scope. If no attr name is specified then the attribute name is assumed to be the same as the local name. Given and widget definition of scope: { localFn:'&myAttr' }, then isolate scope property localFn will point to a function wrapper for the count = count + value expression. Often it's desirable to pass data from the isolated scope via an expression and to the parent scope, this can be done by passing a map of local variable names and values into the expression wrapper fn. For example, if the expression is increment(amount) then we can specify the amount value by calling the localFn as localFn({amount: 22}).

http://docs.angularjs.org/guide/directive

I'm having some difficulty understanding exactly what this statement is telling me. So, what I have tried to do is this...

First the ngRepeat directive being used along with my directive in "testTemplate":

<ul>
   <li my-attr="test()" my-directive ng-repeat="value in values" class="span2">
   </li>
</ul>

Next, my directive defined:

angular.module('myModule', [])
       .directive('myDirective', function() {
            return {
                replace : true,
                transclude : true,
                scope : {
                    test: '&myAttr'
                },
                templateUrl: 'partials/myTemplate.html',
                link : function(scope, element, attrs) {
                    alert(scope.count);
                }
            }
        });

Now finally, I'm trying to define the "test" function within the controller for the parent template where the directive is being referenced.

function TestTemplateCtrl($scope, testTemplate) {
    $scope.test = function() {
        alert('in test');
        $scope.count = "1";
    }
}

So the first problem is that my "test" function in the parent is not being executed at all. Maybe I'm not understanding how the test function within the parent controller should be called. Now I'm not actually increasing yet either, but is the above the correct way I would go about increasing my count when I do get to that point if I can get the test function to fire?

Answer

Mark Rajcok picture Mark Rajcok · Jan 3, 2013

Instead of scope.$parent.$index you might consider passing $index as a directive attribute:

<li my-directive index="{{$index}}" ng-repeat="value in values">

Directive:

myApp.directive('myDirective', function() {
    return {
        replace: true,
        // transclude: true,
        scope: {
            index: '@'
        },
        template: '<div>testing {{index}}</div>',
        link: function(scope, element, attrs) {
            // ...
        }
    }
});

Fiddle.