2013-11-28 9 views
6

「プレイリスト」のような種類のアプリを構築しています。これはng-repeatedカスタムディレクティブで表されます。ng-repeat = "element in playlist"ng-repeatで重複要素を処理する

プレイリストで同じ要素を2回再利用できるようにしたいので、私はtrack by $indexを追加しようとしました。

今は、どのような混乱のは次のとおりです。奇妙が起こっ

$scope.removeElement = function(index){ 
    $scope.playlist.splice(index, 1); 
} 

何か:私はプレイリストから要素を削除するために来たときに(私は基本的にこのようなものが含まれている機能removeElement(index)を持っている要素はから正しく削除されました$scope.playlist、何らかの理由でビューが正しく更新されませんでした。最後の要素が削除されるように見えた。

さらに、私は適切にどちらかの配列の要素を順に再ことができませんでした。

track by $indexを削除したときにこの問題が解消されたので、配列から項目を削除すると、インデックスだけを見ていると最後のものが削除されたように見えます。

トランスクルードコンテンツが正しく削除されているため、動作が、しかし奇妙である - see this plunker

EDIT:上記のリンクは、より良い問題を示し、また、私は落ち着い答えを表示するように変更されました。

私は何を得ていたのかを明確にするため、質問もわずかに編集されています。下記のKayakDaveの答えは正しいですが、プリミティブの配列(私の元のプランカーが特集していたもの)の方が適しています。

TL; DR:はどのように自分の位置を制御する、または正しく構成要素を除去する能力を犠牲にすることなくng-repeatで重複要素を入れていますか?

答えて

5

私は簡単な解決策を発見したので、私は、この質問に別の答えを追加したいと思います。

ng-repeatのための重要なsection of the documentationがあります。これは特に、誤字のエラーでは見逃しやすいものです。

それは述べている:デフォルトで

は、コレクションがこれを読んだ後、参照

をキーとしている、解決策は明らかだった - 私はプリミティブ(はい、plunkerを扱っていなかったとして、それがオーバーシンプル化コピー複製オブジェクトをコピーし、そのコピーを配列に追加する必要がありました。つまり、$ indexでトラックを削除し、デフォルトの動作を継承させると、すべてが正常に動作することを意味します。

Angularは、jqliteが.copyであるため、これを特に簡単にします。方法。

ここに私が言っているのはdemonstrated in a plunkerです。

+0

これを示す最新のプランナーを投稿できますか?これは、同じ問題が発生するように思えます。なぜなら、問題はコレクション/オブジェクトキーだとは思われませんが、私はまだ不一致が予想される '$ index'との相関関係です。だから、私は何が欠けているのか分からない。そして、あなたが投稿したのと同じ問題を抱えている人たちが、あなたのソリューションをよりよく理解できるように助けてくれるでしょう。 – KayakDave

+0

あなたは正しいです。私がここで言わないことは、 'track by $ index'を使う代わりにこれが使えるということです。 '$ by track by $ index'はプリミティブに必要ですが、私のポストのプレイリストの例では、インデックスで追跡するよりも2回インクルードしたいトラックをコピーするほうが理にかなっています。 –

+0

それは今意味があります。更新していただきありがとうございます。あなたの質問をあまりにも微妙に微調整するかもしれない瞬間があったら、 "$ indexでトラックを使用している場合、どのようにng-repeat配列から要素を正しく削除するのですか?"という質問を要約します。あなたはもっと広い質問に今答えていると思います。ちょうどこれがすべて将来の世代に役立ちます:) – KayakDave

7

track byを使用することによる大きなパフォーマンス上の利点の1つは、角度表示がトラッキング式が変更されていないDOM要素には触れないことです。これは、長いng-repeatのリストと、track byの追加の理由の1つのための巨大なパフォーマンス改善です。

パフォーマンスの最適化は、見ているものの根源です。

あなたはそれを作成し、各DOM要素を結びつけるためにng-repeatを言っているtrack by$indexを使用

ng-repeatの最初の実行上の位置( $index)です。

だから、色スタイルの赤を持つ要素が0タグ付けされ、オレンジ1、2、黄色...そして最終的には5

あなたは、インデックスの色角度ルックスを削除すると、あなたが追跡することを告げたとことを見ているの藍あなたのリストは以前より短くなっているので、あなたはインデックス#5を持っている方が長くなります。したがって、 "indigo"という色のスタイルを持つ5-要素タグ付きDOM要素が削除されます。インデックス#2があるので、黄色の要素はそのままです。

紛らわしいことは、データバインディングのために、DOM要素内のテキストが更新されるということです。したがって、「黄色」を削除すると、黄色のDOM要素がテキスト「緑色」を取得します。あなたが見ているものを一言で言えば

は、その要素内のテキストを更新したことが値を追跡しているため、黄色の手つかずでスタイルDOM要素は、(2)はまだ存在しますが、データバインディングを残しng-repeatです。あなたがtrack byに使用する各エントリにあなたの一意の識別子を追加する必要が同じ色で複数のエントリを追加するために

。 1つの方法は、キーが固有の識別子である各エントリに対してキーと値のペアを使用することです。これと同じように:

<color-block ng-repeat="(key, color) in colorlist track by key" color="{{color}}" ng-transclude> 
    {{color}} 
</color-block> 

をそして選択あなたの削除のためにそのキーを使用してください:

$scope.colorlist = {1:'red', 2:'orange',3:'yellow',4:'green',5:'blue',6:'indigo',7:'yellow'}; 
その後

track byキーは次のように今

<option value="{{key}}" ng-repeat="(key,color) in colorlist">{{color}}</option> 

DOM要素を色で黄色のスタイリングは、 "黄色の"配列要素に指定したキーに結び付けられます。したがって、「黄色」を削除すると、ng-repeatは正しいDOM要素を削除し、すべてが機能します。あなたは、それはここで働いて見ることができます

http://plnkr.co/edit/cFaU8WIjliRjPI6LInZ0?p=preview

+0

ありがとう、これは本当に徹底した説明です。私のプランカーのために色で作業するのですが、 'track by $ index'を入れる理由は、リストに要素が重複している可能性があったからです。 ''赤色 '、'青色 '、'赤色 '' 'という選択肢がありますか? **編集**私の質問をより明確にするために、私の冥王星リストに重複を含めるべきだったことを理解しています;) –

+0

できます。私は、(ユニークな識別子を使って)複数の要素を扱うための答えを更新しました。 – KayakDave