2013-03-06 3 views
273

Итак, у меня есть 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 (раздел) ". Передача $ index означает, что вы сделаете цикл, чтобы найти объект, который не нужен. – Moshii

ответ

414

Каждый нг-повтор создает дочернюю сферу с переданными данными, а также добавляет дополнительную $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

Удивительно, так вот как я обращаюсь к внешнему индексу $ index, но мне нужно было передать значения BOTH $ index. Я попытался поместить их в массив, и он сработал :) – Tules

+14

Вам не нужно использовать массив: 'ng-click =" loadFromMenu ($ parent. $ Index, $ index) "' –

+3

вам даже не нужно передайте индексы внутри - в loadFromMenu, он должен иметь доступ к этому объекту, который предоставит вам доступ к этому: $ index и this. $ parent. $ index – Oddman

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-класс.

181

Way более элегантное решение, чем $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

Это рекомендуемый метод достижения этого эффекта. На самом деле угловая команда несколько раз заявляла, что это одно из немногих рекомендуемых применений директивы ng-init (см. [Link] (https://docs.angularjs.org/api/ng/directive/ngInit)). Я часто нахожу, что использование родителя $ (в соответствии с принятым в настоящее время ответом) - это немного запаха кода, так как обычно существует лучший способ достижения связи $ scope с $ scope (Services или Broadcast/Emit Events) и путем назначения его к именованной переменной становится понятнее, что представляет значение. –

+2

ИМО этот ответ лучше, чем принятый. Использование $ parent действительно, действительно неудобно. – olivarra1

29

Просто, чтобы помочь кому-то, кто получит здесь ... Вы не должны использовать $ родительский $ индекс, как это не так. действительно безопасно. Если вы добавите 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 для понимания уникальных элементов и наблюдения за изменениями в коллекции (см. Раздел «Отслеживание и дублирование» в документах: https: // docs.angularjs.org/api/ng/directive/ngRepeat). Важным моментом здесь является «ng-init» - это правильный способ согласования угловых документов. – Rebecca

+0

@gonzalon Как передать этот индекс как параметр в ng click –

+0

Я делаю removeList ($ index) или removeList (rowIndex). Он неправильно записывает индекс в функцию. Я получаю значение индекса как неопределенное. Я использую угловой 1.5.6 – user269867

97

Что об использовании этого синтаксиса (посмотрите в этой 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

На самом деле это вызвало у меня некоторые реальные проблемы при использовании углового ui -tree для перетаскивания узлов. Индекс, похоже, не получает сброс, и в результате возникают странные вещи. –

+0

@MikeTaverne Не могли бы вы попытаться воспроизвести в плункер? Мне бы хотелось увидеть поведение. – Okazari

0

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

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

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