передача 2 $ значений индекса во вложенном ng-repeat

280

Итак, у меня есть ng-repeat, вложенный в другой ng-repeat, чтобы создать навигационное меню. На каждом <li> во внутреннем цикле ng-repeat я устанавливаю ng-click, который вызывает соответствующий контроллер для этого пункта меню, передавая в индекс $index, чтобы приложение узнало, какой из них нам нужен. Однако мне нужно также передать индекс $с внешнего ng-repeat, чтобы приложение узнало, в каком разделе мы находимся, а также в каком учебнике.

<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>

здесь Plunker http://plnkr.co/edit/bJUhI9oGEQIql9tahIJN?p=preview

  • 0
    Почему вы хотите передать $ index? просто передайте ссылку на объект следующим образом: ng-click="loadFromMenu(section)" . Передача $ index означает, что вы выполните цикл, чтобы найти ненужный объект.
Теги:
angularjs-ng-repeat

6 ответов

406
Лучший ответ

Каждый ng-repeat создает дочернюю область с переданными данными, а также добавляет дополнительную дополнительную переменную $index в эту область.

Итак, что вам нужно сделать, это довести до родительской области и использовать $index.

См. 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>
  • 0
    здорово, вот как я получаю доступ к внешнему индексу $, но мне нужно было передать ОБА значениям индекса $. Я попытался поместить их в массив, и это сработало :)
  • 16
    Вам не нужно использовать массив: ng-click="loadFromMenu($parent.$index, $index)"
Показать ещё 11 комментариев
178

Более элегантное решение, чем $parent.$index, использует 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

  • 0
    Работает отлично, не только для функций, но и как часть составного условия класса ng, зависящего от родительских данных
  • 2
    Это рекомендуемый метод достижения этого эффекта. На самом деле команда разработчиков Angular несколько раз заявляла, что это одно из немногих рекомендуемых применений директивы ng-init (см. Ссылку ). Я часто нахожу, что использование $ parent (согласно принятому в настоящее время ответу) немного пахнет кодом, поскольку обычно существует лучший способ достижения связи $ scope с $ scope (Services или Broadcast / Emit Events) и назначением ее для именованная переменная становится понятнее, что представляет собой значение.
Показать ещё 7 комментариев
95

Как насчет использования этого синтаксиса (посмотрите plunker). Я только что открыл это, и это довольно удивительно.

ng-repeat="(key,value) in data"

Пример:

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

С помощью этого синтаксиса вы можете дать свое имя $index и разделить два индекса.

  • 7
    Я думаю, что это намного чище, чем использование родителя, когда у вас есть несколько вложенных циклов
  • 0
    На самом деле это вызвало у меня некоторые реальные проблемы при использовании angular-ui-tree для перетаскивания узлов. Кажется, что индекс не сбрасывается, и в результате происходят странные вещи.
Показать ещё 3 комментария
27

Просто, чтобы помочь кому-то, кто попал сюда... Нельзя использовать $parent. $index, поскольку он не очень безопасен. Если вы добавите ng-if внутри цикла, вы получите $index messed!

Правильный путь

  <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>

Проверьте: plnkr.co/52oIhLfeXXI9ZAynTuAJ

  • 0
    Обратите внимание, что здесь «отслеживать по» не нужно - это отдельная вещь, используемая для ng-repeat для понимания уникальных элементов и отслеживания изменений в коллекции (см. Раздел «Отслеживание и дубликаты» документации: docs.angularjs.org / api / ng / directive / ngRepeat ). Важным моментом здесь является «ng-init» - это правильный путь, с которым согласуются угловые документы.
  • 0
    @gonzalon Как передать этот индекс в качестве параметра в нг клик
Показать ещё 2 комментария
3

Когда вы имеете дело с объектами, вы хотите просто игнорировать простой идентификатор.

Если вы измените линию кликов на это, я думаю, вам будет хорошо на вашем пути:

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

Кроме того, я думаю, вам может потребоваться изменить

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

к чему-то вроде

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

Смотрите http://docs.angularjs.org/misc/faq и найдите ng-класс.

0

Я пытаюсь использовать решение, предложенное Гонсалоном. Но в моем случае это не работает. Я хочу иметь всплывающую подсказку с дополнительной информацией, когда мышь находится над ячейкой таблицы, которую я создаю, зацикливая на строки и ячейки.

Значения изменяются при перемещении мыши над ячейками таблицы, но значения для строки и столбца всегда являются номерами столбцов.

<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>

Ещё вопросы

Сообщество Overcoder
Наверх
Меню