Ng-animate анимировать неправильный элемент при использовании 'track by $index' в ng-repeat

Я пытаюсь создать приложение, в котором пользователь может выбирать различные типы блоков и складывать их вместе для создания уникального шаблона.

Так как я хочу, чтобы пользователь мог добавлять один и тот же блок в шаблон несколько раз, я должен использовать 'track by $index' для выполнения этого:

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

Однако, когда я пытался добавить анимацию с ng-animate, анимация для удаления блока анимация на последнем блоке в шаблоне вместо удаления блока. Я поместил код в jsfiddle здесь http://jsfiddle.net/FC9c7/6/.

Попробуйте добавить новый блок, выбрав макет 1, 2 или 3. И когда вы нажмете "удалить блок", вы увидите проблему.

Ответы

Ответ 1

Вот что я думаю, что это происходит: поскольку вы отслеживаете элементы по их индексам, каждый раз, когда вы удаляете один из списка, какие изменения являются индексом последнего элемента, делая Angular уверенным, что это был тот удален. Это становится очевидным при печати индекса рядом с его элементом. Взгляните на этот измененный jsFiddle.

Одним из решений было бы создавать новые элементы с уникальными идентификаторами, а затем отслеживать эти идентификаторы:

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 эту проблему, и если я узнаю что-то, я обновлю этот ответ. Но я не уверен, что это так.: (

Ответ 2

Вы можете сделать копию объекта, прежде чем добавлять его в выбранный список. Таким образом, вы можете отслеживать по $id (выбранному), который является значением по умолчанию. Вы добавляете один и тот же объект к выбранному списку, поэтому angular будет видеть дубликаты в повторителе для ng-repeat.

измените функцию add_layout следующим образом и удалите дорожку по выражению в ng-repeat. Это просто другое решение. У вас могут быть большие объекты, где выполнение глубокой копии может не иметь смысла.

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

};