在ng-repeat中使用'track by $ index'时,动画错误项目为ng-animate

时间:2013-08-25 19:03:26

标签: javascript animation angularjs

我正在尝试创建一个应用程序,用户可以选择不同类型的块并将它们堆叠在一起以创建独特的模板。

由于我希望用户能够多次将相同的块添加到模板中,因此我必须使用'track by $ index'来实现此目的:

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

但是,当我尝试使用ng-animate添加动画时,删除块的动画会在模板中的最后一个块上生成动画,而不是删除块。我把代码放在jsfiddle http://jsfiddle.net/FC9c7/6/

尝试通过选择布局1,2或3来添加新块。当您单击“删除块”时,您将看到问题。

2 个答案:

答案 0 :(得分:24)

以下是我认为发生的情况:由于您按照索引跟踪项目,因此每次从列表中删除项目时,最后一个元素的索引会发生什么变化,让Angular相信它是被删除的那个。当您在其元素旁边打印索引时,这变得很明显。看看this修改过的jsFiddle。

一种解决方案是创建具有唯一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 here

但是因为它创造了新元素,所以你不能让它们与原始对象保持同步,而且我不知道你是否可以接受它。

我将尝试检查Angular 1.2 RC1中的新动画系统是否解决了这个特定问题,如果我发现了某些内容,我将更新此答案。但是,我对此并不自信。 :(

答案 1 :(得分:3)

您可以在将对象添加到所选列表之前制作该对象的副本。这样您就可以通过$ id(已选择)进行跟踪,这是默认值。您正在将相同的对象添加到所选列表中,因此角度将在转发器中看到重复的ng-repeat。

更改下面的add_layout函数,并在ng-repeat中按表达式删除轨道。 这只是另一种解决方案。您可能有大型对象,执行深层复制可能没有意义。

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

};