Angular ng-repeat анимировать один раз

Я использую ngAnimate для анимации записей в ng-repeat. При загрузке данных все элементы анимируются, как я определил в моем CSS:

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

Это работает, если к уведомлению добавлен следующий 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>

Однако, когда добавляется новое сообщение (вверху), каждый элемент снова анимируется. Есть ли способ анимировать элементы только один раз? Что, когда к массиву добавляется новое сообщение, будет анимироваться только этот элемент?

JSFIDDLE

ИЗМЕНИТЬ

После нескольких щелчков мышью по «новому сообщению» я вижу, что не все уведомления анимированы. Может это как-то связано с ng-repeat-start и ng-repeat-end?


person devqon    schedule 26.05.2015    source источник


Ответы (2)


Даже приведенный выше ответ устранил проблему, мое решение может быть полезно в других сценариях. Исправить довольно просто.

Используйте Angular varible $ first и просто добавьте класс CSS для первого элемента, используя директиву ng-class в вашем HTML. В этом примере класс «first» будет добавлен только к первому элементу в ng-repeat:

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

а затем примените правила анимации к элементу с «первым» классом CSS.

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

Обновленный JSFIDDLE: http://jsfiddle.net/t6x3a1zj/7/

person Michael Money    schedule 26.05.2015
comment
Это звучит как хорошее решение, но все же наблюдается странное поведение: когда несколько уведомлений добавляются друг за другом, не все анимируются. - person devqon; 26.05.2015
comment
Мне нужно было бы воссоздать эту ошибку, прежде чем я смогу вам помочь. Вы ссылаетесь на мой пример - jsfiddle.net/t6x3a1zj/7? - person Michael Money; 26.05.2015
comment
Да, вы можете увидеть это в своем примере, когда два сообщения бота идут друг за другом, только первое анимировано: jsfiddle.net/t6x3a1zj/10 - person devqon; 26.05.2015
comment
Думаю, я понял это. Проблема вызвана отслеживанием по $ index. После снятия работает как шарм. Проверить мое обновление jsfiddle - ›jsfiddle.net/t6x3a1zj/11 - person Michael Money; 27.05.2015
comment
Ты прав! Это довольно странно. Я собираюсь сообщить о проблеме с angular, спасибо! - person devqon; 27.05.2015

Если все правильно поняли, просто измените это:

$scope.messages.unshift(message);

к этому:

$scope.messages.push(message);
person Vassilis Pits    schedule 26.05.2015
comment
Вау, я думал, вы меня не поняли, но, похоже, это решает проблему! Ваш ответ открыл мне глаза, что (конечно же!) Каждый элемент анимируется, потому что он занимает новую позицию в массиве, следовательно, они «входят». Спасибо :) - person devqon; 26.05.2015
comment
Всегда приятно помогать :) Если вы хотите, чтобы я отредактировал свой ответ на то, что вы ожидаете, пожалуйста, попросите меня это сделать. - person Vassilis Pits; 26.05.2015
comment
Единственная проблема здесь в том, как я могу отобразить ng-repeat в обратном порядке? - person devqon; 26.05.2015
comment
ng-repeat-start="message in messages | orderBy:date:true" и вы готовы. - person Vassilis Pits; 26.05.2015
comment
Похоже, orderBy:'date':true не работает в сочетании с ng-repeat-start - person devqon; 26.05.2015
comment
Не при использовании push вместо unshift - person devqon; 26.05.2015
comment
Извините, возможно, вам нужно задать другой вопрос. Fo4 мне кажется работает. Я попробую еще раз kater для решения diff - person Vassilis Pits; 26.05.2015
comment
Позвольте нам продолжить это обсуждение в чате. - person devqon; 26.05.2015