Why do CSS transitions occur for unshift () and not shift () in ng-repeat lists?

I move some elements on the page using ng-repeat and CSS transitions. If I modify the data array using unshift , the list goes well. (In my application, I change the position as well as the opacity.)

However, if I use shift to update the array, the DOM is updated immediately without a jump.

Here's a demonstration of one approach where everything works as expected, except for transitions. Compare the behavior when using two buttons.

 $scope.items.push( $scope.items.shift() ); 

Here is another demonstration of an alternative approach where transitions work, but the array loses an element each time the function runs.

 $scope.items.shift( $scope.items.push() ); 

The idea is that the user can cycle through the elements in the array infinitely cyclically, and CSS transitions occur in both directions. The problem seems to be that AngularJS updates the DOM in one case, but not in the other, although I could not demonstrate this in my testing.

Also, based on some reading, I tried to use track by item.id avail. Many thanks.

+8
javascript arrays angularjs css-transitions angularjs-ng-repeat ng-repeat
source share
3 answers

Really curious.

I played with various possible solutions, and I found that if you change the slide up to

 $scope.slideUp = function() { $scope.items.push( angular.copy($scope.items.shift()) ); }; 

It will animate the third element. So this could be a reference problem in angular?

Note. In my fiddle below, during the game, I also made changes to your ng-class and css, but it still works with your first demo script.

Demo

+2
source share

Another way to do this instead of creating a new object each time is to trick Angular ng-repeat into considering it to be a new object.

 $scope.inc = 9; $scope.slideUp = function() { var item = $scope.items.shift(); item.id = $scope.inc++; $scope.items.push( item ); }; $scope.slideDown = function() { var item = $scope.items.pop(); item.id = $scope.inc++; $scope.items.unshift( item ); }; 

I added the id property to each object that I increase when moving up or down, then set ng-repeat to track by id:

Demo

0
source share

I think I understand your problem.

In your first β€œmalfunctioning” demo, you can see that when you click Move Up, Item One will indeed disappear, but will appear at the bottom of the page! This is because you add it as the last element, and only then does it begin its transition.

In Sliding down an element is simply shifted down and, therefore, you will see the transition more intuitively, namely, associated with the first three elements, but in fact the same thing happens.

What else puzzles me is why the Asok solution works as you expect. I will edit when I think about the reason.

0
source share

All Articles