15

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

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

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

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

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

4

2 回答 2

24

这就是我认为正在发生的事情:由于您正在通过索引跟踪项目,因此每次从列表中删除一个时,最后一个元素的索引会发生变化,从而使 Angular 相信它是被删除的那个。当您在其元素旁边打印索引时,这变得很明显。看看这个修改后的 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在这里

但是由于它创建了新元素,您将无法使它们与原始对象保持同步,我不知道您是否可以接受。

我将尝试检查 Angular 1.2 RC1 中的新动画系统是否解决了这个特定问题,如果我发现了什么,我会更新这个答案。但我不相信它确实如此。:(

于 2013-08-25T19:55:06.050 回答
3

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

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

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

};

于 2014-07-10T21:55:08.410 回答