2

I am using ngAnimate to animate entries in an ng-repeat. When loading the data all elements are animated as I have defined in my css:

.chat-message.notice.ng-enter {
    -webkit-animation: rubberBand 1s;
    -moz-animation: rubberBand 1s;
    -ms-animation: rubberBand 1s;
    animation: rubberBand 1s;
}

This works when a notice is appended with the following html:

<ul>
    <li class="media chat-message pointer fade-animate"
        ng-repeat-start="message in guestbook.messages track by $index"
        ng-if="!message.bot">
        <!-- more html -->
    </li>
    <li class="chat-message notice" ng-repeat-end ng-if="message.bot">
        <div>
            <p class="text-center">
                {{ message.message }}
                <small>({{ message.date | amTimeAgo }})</small>
                <span class="close pull-right" ng-click="guestbook.remove(message)">&times;</span>
            </p>
        </div>
    </li>
</ul>

However, when a new message is appended (at the top), every element is again animated. Is there a way that elements animate only once? That when a new message is appended to the array, only that element will animate?

JSFIDDLE

EDIT

After a few clicks on a 'new message', I can see not all notices are animated. Maybe it has something to do with the ng-repeat-start and ng-repeat-end?

2 Answers 2

2

If understood correctly just change this:

$scope.messages.unshift(message);

to this:

$scope.messages.push(message);
Sign up to request clarification or add additional context in comments.

8 Comments

Wow I thought you did not understand me, but is seems it fixes the issue! Your answer opened my eyes that (off course!) every element is animated because they gain a new position in the array, hence they 'enter'. Thank you :)
It feels always nice to help :) If you would like me to edit my answer to what you're expecting please to do ask me to do it.
The only issue here is how can I then display the ng-repeat in reversed order?
ng-repeat-start="message in messages | orderBy:date:true" and you're ready.
It looks like the orderBy:'date':true doesn't work in combination with an ng-repeat-start
|
1

Even above answer fixed the problem, my solution might be helpful in other scenarios. The fix is pretty straightforward.

Use Angular varible $first and just add CSS class for the first element using ng-class directive in your HTML. In this example, class "first" will be added only to first element in ng-repeat:

ng-class="{'first': $first===true}"

and then apply animation rules to element with "first" CSS class

.chat-message.notice.first.ng-enter {
    color:red !important;
    font-weight:bold;
    animation: rubberBand 1s;
}

Updated JSFIDDLE: http://jsfiddle.net/t6x3a1zj/7/

5 Comments

This sounds like a nice solution, but still there is weird behaviour: when multiple notices are appended after eachother, not all are animated
I would need to recreate this bug, before I could help you. Do you refer to my example - jsfiddle.net/t6x3a1zj/7 ?
Yeah you can see it in your example, when there are 2 bot messages after eachother, only the first one is animated: jsfiddle.net/t6x3a1zj/10
I think i figured it out. The problem is caused by "track by $index". When removed, work like a charm. Check my update jsfiddle --> jsfiddle.net/t6x3a1zj/11
You are correct! That is pretty weird. I'm going to file an issue with angular, thank you!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.