중첩 된 ng-repeat 내에서 2 개의 $ index 값 전달


322

탐색 메뉴를 작성하기 위해 다른 ng-repeat 내에 ng-repeat가 중첩되어 있습니다. <li>내부 ng-repeat 루프에서 각각 ng-click을 설정하여 $ index를 전달하여 해당 메뉴 항목의 관련 컨트롤러를 호출하여 앱에 필요한 것을 알려줍니다. 그러나 외부 ng-repeat에서 $ index를 전달해야 응용 프로그램이 우리가 어느 섹션에 있는지, 어떤 자습서를 알 수 있습니다.

<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


왜 $ index를 전달하고 싶습니까? 이처럼 객체 참조를 전달하십시오 ng-click="loadFromMenu(section)". $ index를 전달하면 불필요한 객체를 찾기 위해 루프를 수행합니다.
Moshii

답변:


468

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

굉장합니다. 그래서 외부 $ 인덱스에 액세스하는 방법이지만 $ index 값을 모두 전달해야했습니다. 나는 그것들을 배열에 넣으려고 노력했다. :)
Tules

16
배열을 사용할 필요는 없습니다. ng-click="loadFromMenu($parent.$index, $index)"
Mark Rajcok

3
loadFromMenu에서 인덱스를 전달할 필요조차 없습니다.이 객체에 액세스 할 수 있어야합니다. this. $ index and this. $ parent. $ index
Oddman

3
@Oddman 비록 이것이 가능하더라도 $ From이있는 범위와 $ index가있는 부모 범위가있는 객체의 컨텍스트에서 실행하도록 loadFromMenu를 하드 와이어 링하는 것이 좋지 않습니다. 예를 들어 메뉴에서 두 개의 중요한 범위 사이에 다른 범위를 생성하는 그룹을 작성한다고 가정하십시오. 호출을 변경하는 대신 loadFromMenu를 변경해야합니다. 그리고 일부 메뉴에서 전화해야하고 일부 메뉴 loadFromMenu($parent.$parent.$index,$index)에서는 loadFromMenu($parent.$index,$index)사용 this....이 작동하지 않습니다.
epeleg

7
실제로 안전하지 않으므로 $ parent. $ index를 사용하지 않아야합니다. 루프 내부에 ng-if를 추가하면 $ index가 엉망이됩니다. plnkr.co/52oIhLfeXXI9ZAynTuAJ
gonzalon

201

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

플 런커 : http://plnkr.co/edit/knwGEnOsAWLhLieKVItS?p=info


2
이 효과를 얻는 데 권장되는 방법입니다. 실제로 각도 팀은 이것이 ng-init 지시문의 몇 가지 권장 사용법 중 하나라고 몇 번 표현했습니다 ( link 참조 ). 나는 $ scope to $ scope 커뮤니케이션 (서비스 또는 방송 / 이벤트 방출)을 달성하는 더 좋은 방법이 있기 때문에 $ parent (현재 허용되는 답변에 따라)의 코드 냄새가 약간 나옵니다. 명명 된 변수 값이 나타내는 것이 더 명확 해집니다.
David Beech

2
IMO이 답변은 허용되는 것보다 낫습니다. $ parent를 사용하는 것은 실제로 조언하지 않습니다.
olivarra1

43
ng-init 값이 다시 초기화되지 않기 때문에 목록에서 항목을 제거하면 작동이 중지됩니다. 목록에서 항목을 제거하지 않으려는 경우에만 유용합니다.
Jesse Greathouse 2014

6
각도 구문이 진화 한 것 같습니다. stackoverflow.com/a/31477492/2516560 이제 "ng-repeat = (키, 값) 데이터"를 사용할 수 있습니다
Okazari

2
당시에 나는이 답변을 썼다. 이것은 Angular 1.X에 대한 방법이었다. 이 사용은 문서에 대한 언급이없는 문서 ng-init에서 입증 되었으므로 여기에 썼습니다 + Github의 문서를 수정했습니다. 현재 구문은 이것을 달성하는 더 좋은 방법을 가지고 있으며, 이는 @Okazari에 의해 입증됩니다. 의견에 언급 된 결함이 없습니다. ng-initng-repeatng-repeat
vucalur

115

이 구문을 사용하는 것은 어떻습니까 (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하면 두 개의 색인에 고유 한 이름을 지정 하고 구별 할 수 있습니다 .


8
나는이 여러 중첩 루프가 부모를 사용하는 것보다 훨씬 깨끗하다고 생각
Yasitha Waduge

실제로 이것은 angular-ui-tree를 사용하여 노드를 드래그 앤 드롭 할 때 실제 문제를 일으켰습니다. 인덱스가 재설정되지 않는 것처럼 보이며 이상한 결과가 발생합니다.
Mike Taverne

@MikeTaverne 당신은 플런저에서 재현하려고 할 수 있습니까? 나는 그 행동을보고 싶다.
Okazari

4
이것이 올바른 달성 방법이며 잠재적 인 문제를 피할 수 있습니다. ng-init는 초기 렌더에서 작동하지만 페이지에서 객체가 업데이트되면 중단됩니다.
Eric Martin

좋은! plunker 예제와 같이 "track by"를 추가하여 수정하십시오.
Danilo

32

여기에 오는 누군가를 돕기 위해 ... $ parent. $ index는 안전하지 않으므로 사용해서는 안됩니다. 루프 안에 ng-if를 추가하면 $ index가 엉망이됩니다!

올바른 방법

  <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


여기서 "추적"은 ​​필요하지 않습니다. 개별 항목을 이해하고 컬렉션의 변경 사항을 감시하기 위해 ng-repeat에 사용되는 별도의 작업입니다 (문서의 "추적 및 복제"섹션 참조). docs.angularjs.org / api / ng / directive / ngRepeat ). 여기서 중요한 점은 "ng-init"입니다. 이것은 각도 문서가 동의하는 올바른 방법입니다.
Rebecca

@gonzalon ng click에서이 색인을 매개 변수로 전달하는 방법
Nagaraj S

removeList ($ index) 또는 removeList (rowIndex)를 수행하고 있습니다. 인덱스 값을 undefined로받는 함수에서 인덱스를 올바르게 기록하지 않습니다. 나는 각 1.5.6 사용하고 있습니다
user269867

이것은 올바른 방법입니다, 당신은 절대로 부모님에게 접근해서는 안됩니다
Jesú Castillo

3

객체를 다룰 때, 간단한 id를 편리하게 무시하고 싶을 것이다.

클릭 라인을 이것으로 변경하면 나아갈 것입니다.

<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을 하고 겨 클래스를 찾습니다.


1

그냥 사용 ng-repeat="(sectionIndex, section) in sections"

그리고 그것은 다음 단계 ng-repeat down에서 사용할 수 있습니다.

<ul ng-repeat="(sectionIndex, section) in sections">
    <li  class="section_title {{section.active}}" >
        {{section.name}}
    </li>
    <ul>
        <li ng-repeat="tutorial in section.tutorials">
            {{tutorial.name}}, Your section index is {{sectionIndex}}
        </li>
    </ul>
</ul>
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.