ผ่าน 2 $ index index ภายใน ng-repeat ที่ซ้อนกัน


322

ดังนั้นฉันจึงมี ng-repeat ซ้อนกันภายใน ng-repeat อื่นเพื่อสร้างเมนู nav ในแต่ละ<li>วงวนซ้ำภายในฉันตั้งค่า ng-click ซึ่งเรียกตัวควบคุมที่เกี่ยวข้องสำหรับรายการเมนูนั้นโดยการผ่านดัชนี $ เพื่อให้แอปทราบว่าเราต้องการอะไร อย่างไรก็ตามฉันจำเป็นต้องผ่านในดัชนี $ จากนอก 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


ทำไมคุณต้องการผ่าน $ index ng-click="loadFromMenu(section)"เพียงแค่ผ่านการอ้างอิงวัตถุเช่นนี้ ผ่านดัชนี $ หมายความว่าคุณจะทำวงเพื่อหาวัตถุที่ไม่จำเป็น
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>

ยอดเยี่ยมนั่นคือวิธีที่ฉันเข้าถึงดัชนีภายนอก แต่ฉันต้องผ่านค่าดัชนีทั้ง BOTH $ ฉันลองใส่มันเข้าไปในอาเรย์และมันก็ใช้งานได้ :)
Tules

16
คุณไม่ต้องใช้อาร์เรย์: ng-click="loadFromMenu($parent.$index, $index)"
ทำเครื่องหมาย Rajcok

3
คุณไม่จำเป็นต้องผ่านดัชนีใน - ใน loadFromMenu ก็ควรมีสิทธิ์เข้าถึงวัตถุนี้ซึ่งจะช่วยให้คุณเข้าถึง: นี่. $ index และสิ่งนี้ $ parent $ index
Oddman

3
@Oddman แม้ว่าจะเป็นไปได้ แต่ฉันไม่คิดว่ามันจะเป็นความคิดที่ดีเพราะคุณต้องเชื่อมโยง loadFromMenu ของคุณเพื่อให้ทำงานในบริบทของวัตถุที่มีขอบเขตที่มี $ index และขอบเขต parent ที่มี $ index สมมติว่าตัวอย่างเช่นคุณสร้างกลุ่มภายในเมนูที่สร้างขอบเขตอื่น ๆ ระหว่างสองกลุ่มที่สำคัญ - คุณจะต้องเปลี่ยน loadFromMenu แทนการเปลี่ยนการโทร และถ้าในบาง menues คุณต้องโทรloadFromMenu($parent.$parent.$index,$index)และในบางอย่างที่คุณต้องการเพียงแค่loadFromMenu($parent.$index,$index)ใช้แล้วก็this....จะไม่ทำงาน
epeleg

7
คุณไม่ควรใช้ $ parent $ $ เพราะมันไม่ปลอดภัยจริงๆ หากคุณเพิ่ม ng-if ในลูปคุณจะได้รับ $ index messed ให้ตรวจสอบ: 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 (ดู: ลิงค์ ) ฉันมักจะพบการใช้ $ parent (ตามคำตอบที่ยอมรับในปัจจุบัน) เป็นบิตของกลิ่นรหัสเนื่องจากโดยปกติแล้วจะมีวิธีที่ดีกว่าในการบรรลุ $ scope เพื่อการสื่อสาร $ scope (บริการหรือกิจกรรมออกอากาศ / ส่งเสียง) และโดยมอบหมายให้ ตัวแปรที่กำหนดชื่อแล้วจะกลายเป็นสิ่งที่ชัดเจนว่าค่าหมายถึงอะไร
David Beech

2
IMO คำตอบนี้ดีกว่าคำตอบที่ได้รับ การใช้พาเรนต์ $ ไม่ใช่ข้อด้อยจริงๆ
olivarra1

43
สิ่งนี้จะหยุดทำงานเมื่อคุณลบรายการออกจากรายการเนื่องจากค่า ng-init ไม่ได้เริ่มต้นใหม่ จะมีประโยชน์ก็ต่อเมื่อคุณไม่ต้องการลบรายการออกจากรายการ
Jesse Greathouse

6
ดูเหมือนว่าไวยากรณ์เชิงมุมวิวัฒนาการ stackoverflow.com/a/31477492/2516560ตอนนี้คุณสามารถใช้ "ng-repeat = (คีย์, ค่า) ในข้อมูล"
Okazari

2
ย้อนกลับไปในวันก่อนฉันเขียนคำตอบนี้นี่เป็นวิธีที่ทำได้สำหรับ Angular 1.X การใช้งานng-initนี้แสดงให้เห็นในng-initเอกสารที่ไม่มีการกล่าวถึงในng-repeatเอกสารดังนั้นฉันจึงเขียนที่นี่ + แก้ไขเอกสารใน Github ng-repeatไวยากรณ์ปัจจุบันมีวิธีที่ดีกว่าในการบรรลุเป้าหมายซึ่งแสดงโดย @Okazari ไม่มีข้อบกพร่องบางอย่างที่คุณกล่าวถึงในความคิดเห็น
vucalur

115

สิ่งที่เกี่ยวกับการใช้ไวยากรณ์นี้ (ดูที่พลันเกอร์นี้) ฉันเพิ่งค้นพบสิ่งนี้และมันก็สวยมาก

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
ฉันคิดว่า
มันดี

ที่จริงแล้วสิ่งนี้ทำให้ฉันมีปัญหาจริงเมื่อใช้ angular-ui-tree เพื่อลาก / วางโหนด ดูเหมือนว่าดัชนีจะไม่ได้รับการรีเซ็ตและสิ่งแปลก ๆ ก็เกิดขึ้น
Mike Taverne

@MikeTaverne คุณลองสร้างมันซ้ำแล้วซ้ำอีกใน plunker ได้ไหม? ฉันชอบที่จะเห็นพฤติกรรม
Okazari

4
นี่เป็นวิธีที่ถูกต้องในการทำสิ่งนี้ให้สำเร็จและหลีกเลี่ยงปัญหาที่อาจเกิดขึ้น ng-init ใช้งานได้กับการเรนเดอร์เริ่มต้น แต่ถ้าวัตถุนั้นได้รับการอัพเดตบนหน้า
Eric Martin

ดี! แต่โปรดแก้ไขด้วยการเพิ่ม "ติดตามโดย" เช่นตัวอย่างของผู้รวบรวม
Danilo

32

เพียงเพื่อช่วยคนที่มาที่นี่ ... คุณไม่ควรใช้ $ parent $ $ เพราะมันไม่ปลอดภัยจริงๆ หากคุณเพิ่ม 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


โปรดทราบว่าไม่จำเป็นต้องใช้ "แทร็กโดย" ที่นี่ซึ่งเป็นสิ่งแยกต่างหากสำหรับ ng-repeat เพื่อทำความเข้าใจกับรายการที่ไม่ซ้ำกันและดูการเปลี่ยนแปลงในคอลเลกชัน (ดูที่ส่วน "การติดตามและทำซ้ำ" ของเอกสาร: docs.angularjs.org / api / ng / directive / ngRepeat ) จุดสำคัญที่นี่คือ "ng-init" - เป็นวิธีที่ถูกต้องที่เอกสารเชิงมุมเห็นด้วย
รีเบคก้า

@gonzalon วิธีผ่านดัชนีเหล่านี้เป็นพารามิเตอร์ใน ng click
Nagaraj S

ฉันกำลังทำ removeList ($ index) หรือ removeList (rowIndex) มันไม่ได้บันทึกดัชนีอย่างถูกต้องในฟังก์ชั่นที่ฉันได้รับค่าดัชนีเป็นไม่ได้กำหนด ฉันใช้มุมฉาก 1.5.6
269867

นี่เป็นวิธีที่ถูกต้องคุณไม่ควรเข้าถึง $ parent
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และค้นหา ng-class


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.