Search code examples
javascripthtmlangularjsangularjs-scopeangularjs-ng-repeat

AngularJS inner ng-repeat not processing $index.$parent in function argument


Could someone more experienced than I explain to me why this compiles:

    <li class="btn dropdown top-stack breadcrumb-btn" ng-repeat="nodeName in selectedNodeNames">
        <a class="dropdown-toggle btn-anchor">{{nodeName}}</a>
        <ul class="dropdown-menu">
            <li ng-class="activeState($parent.$index,$index)" ng-repeat="node in selectedNodeAtLevel($index).children">
                <a ng-click="tabSelect($parent.$index,$index)">{{getIndexString(node)}}</a>
            </li>
        </ul>
    </li>

And the inner ng-repeat in this doesn't?

    <li class="btn dropdown top-stack breadcrumb-btn" ng-repeat="nodeName in selectedNodeNames">
        <a class="dropdown-toggle btn-anchor">{{nodeName}}</a>
        <ul class="dropdown-menu">
            <li ng-class="activeState($parent.$index,$index)" ng-repeat="node in selectedNodeAtLevel($parent.$index).children">
                <a ng-click="tabSelect($parent.$index,$index)">{{getIndexString(node)}}</a>
            </li>
        </ul>
    </li>

Note that I am calling the selectedNodeAtLevel() function with $parent.$index, rather than just $index. Why will it compile for the one and not the other? And what can I do to achieve the same effect?

(By "compile" I mean that it does not generate any HTML, just a commented-out copy of the offending line)

Thanks for your patience!


Solution

  • First let me point out that ng-repeat creates new scope. Also, I'm assuming that the outer repeat does not sit inside yet another repeat. Assuming that, notice in your first example that you pass $index to the selectedNodeAtLevel function. This works because $index is defined by the outer repeat and parsed in the context of the scope of the outer repeat. This $index variable corresponds to each nodeName.

    So the second example fails because there is no $index defined in the outer repeat's $parent (which actually refers to the scope of the controller this code sits in).

    In at least the second case, it seems that you expect that $index refers to the inner repeat, but it does not, it refers to the $index defined in the already defined scope. So you should have issues even in your first example with activeState because of the reference there to $parent.$index. Note that referring to $index from inside the inner repeat will refer to the $index on that inner scope.