web-dev-qa-db-ja.com

ng-repeatで 'track by $ index'を使用すると、ng-animateが間違ったアイテムをアニメーション化する

ユーザーがさまざまなタイプのブロックを選択し、それらを積み重ねて独自のテンプレートを作成できるアプリケーションを作成しようとしています。

ユーザーが同じブロックをテンプレートに複数回追加できるようにしたいので、「$ indexによる追跡」を使用してこれを実行する必要があります。

<li ng-repeat="chosen in chosenlist track by $index">

ただし、ng-animateを使用してアニメーションを追加しようとすると、ブロックを削除するためのアニメーションは、削除するブロックではなく、テンプレートの最後のブロックでアニメーション化されます。ここにコードをjsfiddleに入れます http://jsfiddle.net/FC9c7/6/

レイアウト1、2、または3を選択して、新しいブロックを追加してみてください。「ブロックを削除」をクリックすると、問題が発生します。

15
designil

ここで私はそれが起こっていると信じています:インデックスによってアイテムを追跡しているので、リストからアイテムを削除するたびに、最後の要素のインデックスはどのように変化しますかAngularそれは削除されたものでした。その要素の隣にインデックスを印刷すると、それはある程度明白になります。 this 変更されたjsFiddleを見てください。

1つの解決策は、一意のIDで新しい要素を作成し、それらのIDで追跡することです。

Javascript

$scope.add_layout = function(new_layout) {
  new_layout = angular.copy(new_layout);
  new_layout.id = new Date().getUTCMilliseconds();
  $scope.chosenlist.Push(new_layout);
};

[〜#〜] html [〜#〜]

<li ng-repeat="chosen in chosenlist track by chosen.id" ng-animate="'animate'">

jsFiddle ここ

しかし、それは新しい要素を作成するので、元のオブジェクトとの同期を保つことができなくなり、それが受け入れられるかどうかわかりません。

Angular 1.2 RC1の新しいアニメーションシステムがこの特定の問題を解決し、何かを見つけた場合は、この回答を更新するかどうかを確認します。しかし、確信が持てません。しかし、:(

24
Michael Benford

選択したリストに追加する前に、オブジェクトのコピーを作成できます。この方法では、デフォルトである$ id(chosen)で追跡できます。選択したリストに同じオブジェクトを追加しているので、angularはng-repeatのリピーターに重複を表示します。

add_layout関数を次のように変更し、ng-repeatの式によるトラックを削除します。これは単なる別のソリューションです。ディープコピーを実行しても意味がない大きなオブジェクトがある場合があります。

$scope.add_layout = function(new_layout) {
    $scope.chosenlist.Push(angular.copy(new_layout));

};

3
Philip Leicht