Home » Angularjs » passing 2 $index values within nested ng-repeat

passing 2 $index values within nested ng-repeat

Posted by: admin November 2, 2017 Leave a comment

Questions:

So I have an ng-repeat nested within another ng-repeat in order to build a nav menu. On each <li> on the inner ng-repeat loop I set an ng-click which calls the relevant controller for that menu item by passing in the $index to let the app know which one we need. However I need to also pass in the $index from the outer ng-repeat so the app knows which section we are in as well as which tutorial.

<ul ng-repeat="section in sections">
    <li  class="section_title {{section.active}}" >
        {{section.name}}
    </li>
    <ul>
        <li class="tutorial_title {{tutorial.active}}" ng-click="loadFromMenu($index)" ng-repeat="tutorial in section.tutorials">
            {{tutorial.name}}
        </li>
    </ul>
</ul>

here’s a Plunker http://plnkr.co/edit/bJUhI9oGEQIql9tahIJN?p=preview

Answers:

Each ng-repeat creates a child scope with the passed data, and also adds an additional $index variable in that scope.

So what you need to do is reach up to the parent scope, and use that $index.

See http://plnkr.co/edit/FvVhirpoOF8TYnIVygE6?p=preview

<li class="tutorial_title {{tutorial.active}}" ng-click="loadFromMenu($parent.$index)" ng-repeat="tutorial in section.tutorials">
    {{tutorial.name}}
</li>

Questions:
Answers:

Way more elegant solution than $parent.$index is using ng-init:

<ul ng-repeat="section in sections" ng-init="sectionIndex = $index">
    <li  class="section_title {{section.active}}" >
        {{section.name}}
    </li>
    <ul>
        <li class="tutorial_title {{tutorial.active}}" ng-click="loadFromMenu(sectionIndex)" ng-repeat="tutorial in section.tutorials">
            {{tutorial.name}}
        </li>
    </ul>
</ul>

Plunker: http://plnkr.co/edit/knwGEnOsAWLhLieKVItS?p=info

Questions:
Answers:

What about using this syntax (give a look in this plunker). I just discovered this and it’s pretty awesome.

ng-repeat = (key,value) in data

Exemple :

<div ng-repeat="(indexX,object) in data">
    <div ng-repeat="(indexY,value) in object">
       {{indexX}} - {{indexY}} - {{value}}
    </div>
  </div>

With this syntax you can give your own name to $index and differentiate the two indexes.

Questions:
Answers:

Just to help someone who get here… You should not use $parent.$index as it’s not really safe. If you add an ng-if inside the loop, you get the $index messed!

Right way

  <table>
    <tr ng-repeat="row in rows track by $index" ng-init="rowIndex = $index">
        <td ng-repeat="column in columns track by $index" ng-init="columnIndex = $index">

          <b ng-if="rowIndex == columnIndex">[{{rowIndex}} - {{columnIndex}}]</b>
          <small ng-if="rowIndex != columnIndex">[{{rowIndex}} - {{columnIndex}}]</small>

        </td>
    </tr>
  </table>

Check: plnkr.co/52oIhLfeXXI9ZAynTuAJ

Questions:
Answers:

When you are dealing with objects, you want to ignore simple id’s as much as convenient.

If you change the click line to this, I think you will be well on your way:

<li class="tutorial_title {{tutorial.active}}" ng-click="loadFromMenu(tutorial)" ng-repeat="tutorial in section.tutorials">

Also, I think you may need to change

class="tutorial_title {{tutorial.active}}"

to something like

ng-class="tutorial_title {{tutorial.active}}"

See http://docs.angularjs.org/misc/faq and look for ng-class.

Questions:
Answers:

I am trying to use the solution that gonzalon proposed. But it does not work in my case.
I want to have a tooltip with more information when the mouse is over the cell of the table that i create by looping to the rows and cells.

The values change when in move my mouse over the table cells, but the values for row and column are always both the column number.

<div table-data="vm.tableData" ng-if= "vm.table_ready" >

     <b2b-table>
     <table>
         <thead type="header">
             <tr>
                <th ng-repeat = "zone in vm.tableData[0]" >{{zone}}</th>

             </tr>
         </thead>

         <tbody type="body" ng-repeat="row in vm.tableData track by $index" ng-init="rowIndex = $index" ng-if="$index >0" >
             <tr>
               <th>{{row[0]}}</th>
               <td headers="rowheader0" ng-repeat = "cell in row  track by $index" ng-init="columnIndex = $index" ng-if="$index >0"  ng-mouseover="vm.showTooltip(rowIndex, columnIndex)" ng-mouseleave="vm.hideTooltip()" >
                {{cell[1]}}

               </td>
             </tr>
         </tbody>

     </table>
      </b2b-table>

 </div>