ネストされたng-repeat内で2つの$ index値を渡す


322

したがって、ナビゲーションメニューを作成するために、ng-repeatが別のng-repeat内にネストされています。<li>内部のng-repeatループのそれぞれに、$ indexを渡して必要なものをアプリに通知することにより、そのメニュー項目に関連するコントローラーを呼び出すng-clickを設定しました。ただし、外部の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にアクセスしますが、両方の$ index値を渡す必要がありました。私はそれらを配列に入れてみましたが、
うまくいき

16
あなたは、配列を使用する必要はありません: ng-click="loadFromMenu($parent.$index, $index)"
マーク・Rajcok

3
インデックスを渡す必要もありません-loadFromMenuでは、thisオブジェクトへのアクセス権が必要です。これにより、this。$ indexおよびthis。$ parent。$ indexにアクセスできます
Oddman

3
@Oddmanこれは可能ですが、loadFromMenuを$ indexのスコープと$ indexの親スコープを持つオブジェクトのコンテキストで実行するように配線するので、私はそれは良い考えではないと思います。次に、たとえば、2つの重要なグループの間に別のスコープを生成するメニュー内にグループを作成するとします。呼び出しを変更する代わりに、loadFromMenuを変更する必要があります。いくつかのmenuesにあなたが呼び出す必要がある場合やloadFromMenu($parent.$parent.$index,$index)、いくつかであなただけの必要がloadFromMenu($parent.$index,$index)その後、使用してthis....の作業だけではないだろう。
epeleg 2014年

7
安全ではないため、$ parent。$ indexは使用しないでください。ループ内にng-ifを追加すると、$ indexが混乱します。plnkr.co
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ディレクティブの推奨される数少ない使用法の1つであることを何度か表明しています(リンク:を参照)。$ scopeを$ scopeから$ scopeへの通信(ServicesまたはBroadcast / Emit Events)に達成し、それを名前付き変数は、値が何を表すかが明確になります。
David Beech

2
IMOこの答えは、受け入れられているよりもはるかに優れています。$ parentを使用することは、本当に、あまりお勧めできません。
olivarra1 2014

43
ng-init値は再初期化されないため、リストから項目を削除すると、これは機能を停止します。リストから項目を削除するつもりがない場合にのみ役立ちます。
Jesse Greathouse、2014

6
角度構文が進化したように見えます。stackoverflow.com/a/31477492/2516560「データでng-repeat =(key、value)」を使用できるようになりました
Okazari

2
昔、私がこの回答を書いたとき、これがAngular 1.Xでそれを行う方法でした。このの使用はドキュメントでng-init示され、ng-initドキュメントでの言及は1 ng-repeatつもなかったため、ここに書いて+ Githubのドキュメントを修正しました。現在のng-repeat構文には、これを実現するためのより良い方法があります。これは、@ Okazariによって示されています。コメントであなたが言及したいくつかの欠陥はありません。
vucalur 2016年

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と、2つのインデックスに独自の名前を付けて区別できます。


8
複数のネストされたループがある場合、これは親を使用するよりもはるかにクリーンだと思います
Yasitha Waduge

実際、angular-ui-treeを使用してノードをドラッグ/ドロップすると、実際に問題が発生しました。インデックスがリセットされていないようで、奇妙なことが起こります。
Mike Taverne、2015

@MikeTaverneプランカーで再現してみませんか?私はその行動を見たいです。
Okazari

4
これは、これを実現し、潜在的な問題を回避するための正しい方法です。ng-initは最初のレンダリングで機能しますが、オブジェクトがページ上で更新されると壊れます。
エリックマーティン

良い!ただし、プランカーの例のように「トラックバイ」を追加して修正してください。
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:docs.angularjs.orgの「Tracking and Duplicates」セクションを参照)。/ api / ng / directive / ngRepeat)。ここで重要なのは「ng-init」です。これは、角度付きドキュメントが同意する正しい方法です。
レベッカ

@gonzalonクリックngでこれらのインデックスをパラメーターとして渡す方法
Nagaraj S

removeList($ index)またはremoveList(rowIndex)を実行しています。関数でインデックスが正しく記録されていません。インデックス値をundefinedとして受け取ります。私はangular 1.5.6を使用しています
user269867

これは、あなたがすべきことはありませんアクセス$親正しい方法である
JESUカスティーヨ

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.