ng-repeat visual glitch (previous & new array displayed) - angularjs

I have a glitch with angular's ng-repeat directive. My HTML is as follow:
<ul ng-show="predictions" id="search-place-predictions">
<li ng-repeat="prediction in predictions">{{prediction.description}}</li>
</ul>
and $scope.predictions is an Array in my controller, that takes between 0 and 5 items. However, at each update of this array, I have a visual glitch of around .2 second where the PREVIOUS <li> are still displayed, and the <li> from the new version of the array are also displayed on top of it. No amounts of $apply() have been able to solve this.
EDIT: I have a transition: border-top .2s ease-out; style applied to my list items. When commented out, the glitch disappears.

It's not a bug, per se. Some browsers don't support animation, but angular will still delay hiding and showing by the animation length it detects in your CSS. Usually affects IE <= 9.
See this answer for ways to disable animations in angular.

Related

ngAnimate Flip Animation

I spent the last 5 hours trying to get this animation to work with no luck. I wanted to create a cool animation whenver the user click on a button, the idea is to display a list of ul elements in a flip animation, pretty much like what http://lab.hakim.se/scroll-effects/mobile.html is doing (if you selected flip from the gear icon and changed chrome device mode to a mobile device).
Im using ngAnimate along with Angular and Ionic, I created the snippet here http://play.ionic.io/app/4ae65754fc64 (try to click the Add to Cart button). I want to display each li item as if they are flip and cascading whenever they are displayed. For some reason all the animation classed are ignored.
Ok, I think I achieved what you were wanting to achieve. I provided you two demos below.
But first of all the ng-animate directive is not supported anymore in AngularJS >= 1.2. And for ng-show based animations you have to use the ng-hide-add, ng-hide-remove CSS classes not the CSS classes described in the ngRepeat documentation.
The ionic demo (first link below) is basicly just a mockup of your code and is not perfect by any means.
The codepen demo is a bit more modified example and generic example. I used <ion-list> and <ion-item> instead of <ul> and <li>.
Hopefully this gets you in the right direction when implementing your final solution.
Ionic demo: http://play.ionic.io/app/3c0e90238fe8
Codepen demo (more generic): http://codepen.io/thepio/pen/KMPeZo

ng-animate retains duplicated DOM element on Chrome 49.x

I have problem since the latest Chrome browser was released.
I'm using angular 1.2.0 app with ng-animate included.
In my index file I have container element like
<div id="container" ng-class="{container:$root.container}" ng-view ng-cloak ></div>
Since the latest Chrome release I have the issue, when the transitions are finished the app view ends with 2 container with vertical/horizontal scroll. They become three, four and so on in the DOM after each transition.
The inline css snapshot in Chrome, when I have only two DOM containers is:
class="ng-scope container ng-animate ng-leave ng-animate-start ng-animate-active ng-leave-active"
for the first one and
class="ng-scope container ng-animate ng-enter ng-animate-start ng-animate-active ng-enter-active"
for the second.
The problem is the this is only on Chrome 49. On other browsers it is acting as expected. On firefox for example (same applies for safari) looking at the DOM on the on each transition I can see that the ng-animate creates second element and then removes it. It ends only with
class="ng-scope container"
Anyone with same problem ? I can't see any decent solution for now. I don;t want to add watchers in some parent controller or any similar ugly patch.
Thanks in advance guys!

AngularJS - only animating in one direction?

I have 5 items in an array. When I reshuffle them I only see animations for items that end up with a higher index - the other just jump to the new spot.
<div ng-repeat="item in items track by item.value" class="TestItem" ng-style="{'top' : $index * 20 + 'px'}">
{{item.name}}
</div>
CSS
.TestItem{
transition: all linear 2s;
position: absolute;
}
How can I make all items animate to their new top position??
The elements that end up with a lower index will be removed from the DOM and inserted at their new positions. When elements are added to the DOM their CSS transitions are not animated (at least not in any of the major browsers).
The rest of the elements will remain in the DOM, get new top values and their transitions will be animated.
Below is a demo using ngAnimate and ng-move to color the moving elements red (the ones removed from the DOM ans inserted again). As described above, these are the elements that do not get their top transition animated.
Demo: http://plnkr.co/edit/7QFMSgo60vQ2qfYzqsBI?p=preview
One solution to this problem can be found here.

Watching a CSS property change from Bootstrap in AngularJS

I am working on a responsive website. My site uses Bootstrap 3.1 and AngularJS. Bootstrap has a class called "visible-xs". This class basically says let something be visible on small screens and hidden on larger screens. It does this by changing the CSS display property value between none and block. Currently, I have a div that looks like the following:
<span id="smallContent" class="visible-xs">Mobile Content</span>
I need to do some stuff programmatically in my controller when smallContent changes from visible to hidden and vice-versa. My question is, how do I watch for changes on the display property of smallContent? I've noticed the $watch method on the scope (http://docs.angularjs.org/api/ng/type/$rootScope.Scope). However, this seems to watch for changes to a property in the scope, not for changes to a property in the DOM.
Is there a way to do what I'm trying? If so, how?
Thank you!
You don't need javascript watchers to do what you want. You can, but it would be kind of hacky and potentially bad on performance.
Another point is that "responsiveness" should be handled (a maximum) by HTML/CSS only. If you start having JS different for each resolutions, it's no good.
What you could do :
<span id="smallContent" class="visible-xs">Mobile Content</span>
<span id="smallContent" class="hidden-xs">Not Mobile Content</span>
Keep in mind that you can also simulate media-query in JS with Modernizr :
if (Modernizr.mq('only all and (min-width: 768px)') ) {
}
That can be usefull (you can alos add this to a watcher but, well my answer was primarily CSS-based and you should stick to CSS solutions when possible)

How to prevent animation from running on element that is initially hidden?

My question is similar to this one and this one, but involves the new animations in AngularJS 1.2.0.
Basically, I have a bunch of elements on my signup page that are initially hidden and only displayed when a particular form element is invalid (they point to the invalid form element and display a message like "password needs to be at least 8 characters"). These messages fade in and out as they are shown/hidden.
But as soon as the signup page is displayed the elements are visible and fade out. They are briefly visible (they "blink" or "flash" on the screen, as is the case in situations where ng-cloak is necessary).
Here's a plunker to demonstrate the behaviour that I'm experiencing. In this plunker I have set up a basic route (the "login" page) that contains a box and a button that toggles the box's visibility. Notice how the box fades out when you click run? It should just be hidden. (I've deliberately set the animation to be slow so you can see the animation occurring).
How can I stop the animation from occurring initially?
What I've tried:
Set ng-cloak on the animating elements.
Use ng-cloak with the display: none !important rule added. (See this)
Setting display: none on the element, as if it were an "initial setting" for the element. (See this)
Interestingly, this plunker behaves properly and the animation doesn't occur initially. This plunker doesn't use routing and the controller is set explicitly on the body tag. I want to use routing though.
There's a problem with the version of angular you are using. Angular animate changed a lot I think in 1.2 so try this:
<script src="http://code.angularjs.org/1.2.14/angular.min.js"></script>
<script src="http://code.angularjs.org/1.2.14/angular-animate.min.js"></script>
<script src="http://code.angularjs.org/1.2.14/angular-route.min.js"></script>
Check it out, I've forked your plunker here
http://plnkr.co/edit/Mchjx51GREGU2Gj0NBXX?p=preview

Resources