yuvalanmış ng tekrarında 2 $ endeks değeri geçirme


322

Bu yüzden bir nav menüsü oluşturmak için başka bir ng tekrar içinde yuvalanmış bir ng-tekrar var. <li>İç ng-tekrar döngüsünün her birinde , uygulamanın hangisine ihtiyacımız olduğunu bildirmek için $ dizinini ileterek bu menü öğesi için ilgili denetleyiciyi çağıran bir ng-click ayarladım. Ancak ben de uygulama hangi bölümde olduğu gibi hangi öğretici bilir böylece dış ng-tekrardan $ endeksi geçmek gerekir.

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

İşte bir Plunker http://plnkr.co/edit/bJUhI9oGEQIql9tahIJN?p=preview


Neden $ endeksini geçmek istiyorsunuz? sadece nesne referansını bu şekilde iletin ng-click="loadFromMenu(section)". $ Dizinini geçmek, gereksiz nesneyi bulmak için bir döngü yapacağınız anlamına gelir.
Moshii

Yanıtlar:


468

Her ng tekrarı, iletilen verilerle bir alt kapsam oluşturur ve $indexbu kapsamda ek bir değişken ekler .

Yapmanız gereken şey ana kapsama ulaşmak ve bunu kullanmaktır $index.

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

harika, bu yüzden dış $ endeksi erişmek, ama ben İKİ $ endeksi değerleri geçmek gerekiyordu. Onları bir diziye koymaya çalıştım ve işe yaradı :)
Tules

16
Bir dizi kullanmak zorunda değilsiniz: ng-click="loadFromMenu($parent.$index, $index)"
Mark Rajcok

3
Bu $ endeksi ve bu $ ebeveyn $ endeksi: Eğer erişim verecek bir bu nesnenin, erişimi olmalıdır, loadFromMenu içinde - hatta dizinleri geçmek zorunda değilsiniz...
ufak tefek işler yapan adam

3
@Odman bu mümkün olsa bile, daha sonra zor bir loadFromMenu $ endeksi ve $ endeksi ile üst kapsamı olan bir nesnenin bir bağlamda çalıştırmak için zor gibi iyi bir fikir olduğunu sanmıyorum. Örneğin, menüde iki önemli alan arasında başka bir kapsam oluşturan gruplar oluşturduğunuzu varsayalım - çağrıyı değiştirmek yerine loadFromMenu öğesini değiştirmeniz gerekir. Ve bazı menülerde aramanız gerekiyor loadFromMenu($parent.$parent.$index,$index)ve bazılarında sadece loadFromMenu($parent.$index,$index)o zaman kullanmak this....işe yaramazsa.
epeleg

7
Gerçekten güvenli olmadığı için $ parent. $ Dizinini kullanmamalısınız. Döngünün içine bir ng-if eklerseniz, $ endeksinin dağınık hale gelmesini sağlayın
gonzalon

201

$parent.$indexKullanmaktan çok daha şık bir çözüm 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>

Piston: http://plnkr.co/edit/knwGEnOsAWLhLieKVItS?p=info


2
Bu etkiyi elde etmek için önerilen yöntem budur. Aslında, açısal ekip bunun ng-init yönergesinin önerilen birkaç kullanımından biri olduğunu birkaç kez ifade etmiştir (bakınız: bağlantı ). Genellikle $ üst iletişim (şu anda kabul edilen cevaba göre) bir kod kokusu biraz bulmak için genellikle $ kapsam iletişim (Services veya Broadcast / Emit Events) için $ kapsamı elde etmenin daha iyi bir yolu var ve bir değişken adı verilen değerin neyi temsil ettiği netleşir.
David Beech

2
IMO bu cevap kabul edilenden çok daha iyi. $ Parent kullanmak gerçekten, gerçekten tavsiye edilmez.
olivarra1

43
Bu, ng-init değeri yeniden başlatılmadığı için öğeleri listeden kaldırdığınızda çalışmayı durdurur. Yalnızca öğeleri listeden kaldırmak istemiyorsanız kullanışlıdır.
Jesse Greathouse

6
Görünüşe göre açısal sözdizimi gelişti. stackoverflow.com/a/31477492/2516560 Artık "verilerde ng-repeat = (anahtar, değer)" kullanabilirsiniz
Okazari

2
O zamanlar bu cevabı yazdım, Angular 1.X için bunu yapmanın yolu buydu. Bu kullanımı ng-initgösterildi ng-inithiçbir tek söz ile dokümanlar ng-repeatburada yazdım + Github üzerinde doküman tadil yüzden, docs. Mevcut ng-repeatsözdiziminin bunu başarmak için daha iyi bir yolu vardır, bu da @Okazari tarafından gösterilmiştir. Yorumlarda belirttiğiniz bazı kusurlardan muaftır.
vucalur

115

Bu sözdizimini kullanmaya ne dersiniz (bu dalma makinesine bir göz atın ). Ben sadece bunu keşfettim ve oldukça harika.

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

Misal:

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

Bu sözdizimi ile $indexiki dizine kendi adınızı verebilir ve ayırt edebilirsiniz.


8
Birden fazla iç içe döngüye sahip olduğunuzda, ebeveyn kullanmaktan çok daha temiz olduğunu düşünüyorum
Yasitha Waduge

Aslında bu, düğümleri sürüklemek / bırakmak için açısal-ui ağacını kullanırken bazı gerçek sorunlara neden oldu. Endeks sıfırlanmıyor ve sonuç olarak garip şeyler oluyor.
Mike Taverne

@MikeTaverne Bir dalgıçta yeniden üretmeyi deneyebilir misiniz? Davranışı görmek isterim.
Okazari

4
Bunu başarmanın ve olası sorunlardan kaçınmanın doğru yolu budur. ng-init ilk oluşturma için çalışır, ancak nesne sayfada güncellenirse kırılır.
Eric Martin

iyi! ancak lütfen dalgıç örneği gibi "takip et" ifadesini ekleyerek düzeltin.
Danilo

32

Sadece buraya gelen birine yardım etmek için ... Gerçekten güvenli olmadığı için $ parent. $ Dizinini kullanmamalısınız. Döngünün içine bir ng-if eklerseniz, $ endeksi dağınık hale gelir!

Doğru yol

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

Kontrol: plnkr.co/52oIhLfeXXI9ZAynTuAJ


Burada "takip etme" işleminin gerekli olmadığını unutmayın. Bu, benzersiz öğeleri anlamak ve koleksiyondaki değişiklikleri izlemek için ng-tekrar için kullanılan ayrı bir şeydir (dokümanlardaki "İzleme ve Kopyalar" bölümüne bakın: docs.angularjs.org / api / ng / yönergesi / ng Tekrarlama ). Burada önemli olan nokta "ng-init" dir - açısal belgelerin aynı fikirde olduğu şekildedir.
Rebecca

@gonzalon Bu dizini ng tıklamasında parametre olarak nasıl iletilir
Nagaraj S

RemoveList ($ index) veya removeList (rowIndex) yapıyorum İndeks değerini tanımsız olarak aldığım fonksiyonda indeksi doğru olarak kaydetmiyor. Açısal 1.5.6 kullanıyorum
user269867

Bu doğru yoldur, asla $
parent'e erişmemelisiniz

3

Nesnelerle uğraşırken, basit kimlikleri de uygun olduğu kadar yoksaymak istersiniz.

Tıklama satırını bu şekilde değiştirirseniz, yolunuza çıkacağınızı düşünüyorum:

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

Ayrıca, bence değiştirmeniz gerekebilir

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

gibi bir şeye

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

Bkz. Http://docs.angularjs.org/misc/faq ve ng-sınıfı olup olmadığına bakın.


1

Sadece kullan ng-repeat="(sectionIndex, section) in sections"

ve bu, bir sonraki seviyeden sonra tekrarlanabilir.

<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>
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.