vượt qua 2 giá trị chỉ mục trong vòng lặp ng lồng nhau


322

Vì vậy, tôi có một ng-repeat lồng nhau trong một ng-repeat khác để xây dựng một menu nav. Trên mỗi <li>vòng lặp lặp lại bên trong, tôi đặt ng-click để gọi bộ điều khiển có liên quan cho mục menu đó bằng cách chuyển vào chỉ mục $ để cho ứng dụng biết cái nào chúng ta cần. Tuy nhiên, tôi cũng cần phải vượt qua chỉ số $ từ lặp lại ng-ngoài để ứng dụng biết chúng ta đang ở phần nào cũng như hướng dẫn nào.

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

đây là một Plunker http://plnkr.co/edit/bJUhI9oGEQIql9tahIJN?p=preview


Tại sao bạn muốn vượt qua chỉ số $? chỉ cần vượt qua các tham chiếu đối tượng như thế này ng-click="loadFromMenu(section)". Vượt qua chỉ số $ có nghĩa là bạn sẽ thực hiện một vòng lặp để tìm đối tượng không cần thiết.
Moshii

Câu trả lời:


468

Mỗi ng-repeat tạo ra một phạm vi con với dữ liệu được truyền và cũng thêm một $indexbiến bổ sung trong phạm vi đó.

Vì vậy, những gì bạn cần làm là đạt đến phạm vi cha mẹ và sử dụng nó $index.

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

thật tuyệt vời, vì vậy đó là cách tôi truy cập vào chỉ mục $ bên ngoài, nhưng tôi cần phải vượt qua các giá trị chỉ mục BOTH $. Tôi đã thử đặt chúng vào một mảng và nó hoạt động :)
Tules

16
Bạn không phải sử dụng một mảng: ng-click="loadFromMenu($parent.$index, $index)"
Mark Rajcok

3
bạn thậm chí không phải truyền các chỉ mục vào - trong loadFromMothy, nó sẽ có quyền truy cập vào một đối tượng này, nó sẽ cung cấp cho bạn quyền truy cập vào: this. $ index và this. $
Parent

3
@Oddman mặc dù điều này là có thể nhưng tôi không nghĩ rằng đó là một ý tưởng tốt khi bạn kết nối loadFromMothy của mình để chạy trong bối cảnh của một đối tượng có phạm vi với chỉ mục $ và phạm vi cha mẹ với chỉ mục $. giả sử bạn sau đó tạo các nhóm trong menu tạo ra một phạm vi khác ở giữa hai nhóm quan trọng - bạn sẽ phải thay đổi loadFromMothy thay vì thay đổi cuộc gọi đến nó. Và nếu trong một số mối đe dọa bạn cần gọi loadFromMenu($parent.$parent.$index,$index)và trong một số bạn cần chỉ loadFromMenu($parent.$index,$index)sau đó sử dụng this....sẽ không hoạt động.
epeleg

7
Bạn không nên sử dụng $ Parent. $ Index vì nó không thực sự an toàn. Nếu bạn thêm ng-if bên trong vòng lặp, bạn sẽ thấy chỉ số $ bị rối, hãy kiểm tra: plnkr.co/52oIhLfeXXI9ZAynTuAJ
gonzalon

201

Cách giải quyết thanh lịch hơn $parent.$indexlà sử dụng 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


2
Đây là phương pháp được đề nghị để đạt được hiệu ứng này. Trong thực tế, nhóm góc cạnh đã bày tỏ một vài lần rằng đây là một trong số ít cách sử dụng chỉ thị ng-init (xem: link ). Tôi thường thấy việc sử dụng $ Parent (theo câu trả lời hiện được chấp nhận) là một chút mùi mã vì thường có cách tốt hơn để đạt được phạm vi $ cho giao tiếp phạm vi $ (Dịch vụ hoặc Phát sóng / Phát sự kiện) và bằng cách gán nó cho biến có tên nó trở nên rõ ràng hơn những gì giá trị đại diện.
David Beech

2
IMO câu trả lời này là cách tốt hơn so với chấp nhận. Sử dụng $ cha là thực sự, thực sự không được đánh giá cao.
olivarra1

43
Điều này dừng hoạt động khi bạn xóa các mục khỏi danh sách vì giá trị ng-init không khởi tạo lại. Nó chỉ hữu ích nếu bạn không có ý định xóa các mục khỏi danh sách.
Jesse Greathouse

6
Hình như cú pháp góc phát triển. stackoverflow.com/a/31477492/2516560 bây giờ bạn có thể sử dụng "ng-repeat = (key, value) trong dữ liệu"
Okazari

2
Quay lại những ngày sau đó tôi đã viết câu trả lời này, đây là cách để làm điều đó cho Angular 1.X. Việc sử dụng này ng-initđã được chứng minh trong các ng-inittài liệu không có một đề cập nào trong các ng-repeattài liệu, vì vậy tôi đã viết ở đây + sửa đổi các tài liệu trên Github. ng-repeatCú pháp hiện tại có một cách tốt hơn để đạt được điều này, được thể hiện bởi @Okazari. Nó là miễn phí của một số khiếm khuyết được đề cập bởi bạn trong các ý kiến.
vucalur

115

Điều gì về việc sử dụng cú pháp này (hãy xem trong plunker này ). Tôi mới phát hiện ra điều này và nó thật tuyệt vời.

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

Thí dụ:

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

Với cú pháp này, bạn có thể đặt tên riêng của mình $indexvà phân biệt hai chỉ mục.


8
Tôi nghĩ rằng điều này sạch hơn nhiều so với việc sử dụng cha mẹ khi bạn có nhiều vòng lặp lồng nhau
Yasitha Waduge

Trên thực tế, điều này gây ra cho tôi một số vấn đề thực sự khi sử dụng cây góc cạnh để kéo / thả nút. Chỉ số dường như không được thiết lập lại và kết quả là những điều kỳ lạ xảy ra.
Mike Cheesne

@MikeTaverne Bạn có thể thử sao chép trong một plunker không? Tôi rất thích xem hành vi.
Okazari

4
Đây là cách chính xác để thực hiện điều này và tránh bất kỳ vấn đề tiềm ẩn nào. ng-init hoạt động cho kết xuất ban đầu, nhưng nếu đối tượng được cập nhật trên trang, nó sẽ bị hỏng.
Eric Martin

tốt nhưng vui lòng sửa bằng cách thêm "track by" như ví dụ về plunker.
Danilo

32

Chỉ để giúp ai đó đến đây ... Bạn không nên sử dụng $ Parent. $ Index vì nó không thực sự an toàn. Nếu bạn thêm một ng-if bên trong vòng lặp, bạn sẽ nhận được chỉ số $ bị rối!

Đúng cách

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

Kiểm tra: plnkr.co/52oIhLfeXXI9ZAynTuAJ


Lưu ý rằng "theo dõi" không cần thiết ở đây - đó là một điều riêng biệt được sử dụng để lặp lại để hiểu các mục độc đáo và theo dõi các thay đổi trong bộ sưu tập (xem phần "Theo dõi và trùng lặp" của tài liệu: docs.angularjs.org / api / ng / chỉ thị / ngRepeat ). Điểm quan trọng ở đây là "ng-init" - đó là cách chính xác mà các tài liệu góc cạnh đồng ý.
Rebecca

@gonzalon Cách vượt qua các chỉ số này dưới dạng tham số trong ng click
Nagaraj S

Tôi đang thực hiện removeList ($ index) hoặc removeList (row Index) Nó không ghi chỉ mục chính xác trong hàm Tôi nhận giá trị chỉ mục là không xác định. Tôi đang sử dụng góc 1.5.6
user269867

Đây là cách đúng đắn, bạn không bao giờ nên truy cập $
Parent

3

Khi bạn đang làm việc với các đối tượng, bạn muốn bỏ qua id đơn giản càng nhiều càng thuận tiện.

Nếu bạn thay đổi dòng nhấp chuột vào đây, tôi nghĩ bạn sẽ ổn trên con đường của mình:

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

Ngoài ra, tôi nghĩ rằng bạn có thể cần phải thay đổi

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

đến một cái gì đó như

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

Xem http://docs.angularjs.org/misc/faq và tìm ng-class.


1

Chỉ dùng ng-repeat="(sectionIndex, section) in sections"

và điều đó sẽ được sử dụng ở cấp độ tiếp theo ng-lặp xuống.

<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>
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.