ng-animate: только добавить к dom после задержки анимации



Я пытаюсь использовать ng-animate с ng-repeatng-show), чтобы удалить старое содержимое и заменить его новым.



Проблема, с которой я сталкиваюсь, заключается в том, что во время анимации remove и add как добавляемые, так и удаляемые элементы имеют display:block.



Я думал, что смогу избежать этого, используя animation-delay в CSS, но это просто задерживает затухание, а не добавление класса, который устанавливает display на элемент.



В результате получается скачкообразный переход.

Это это моя анимация CSS (вырубить):



.keyframe-fade.ng-enter,
.keyframe-fade.ng-move {
animation: 0.5s fade-in;
animation-delay: 1s;
animation-fill-mode: backwards;
}
.keyframe-fade.ng-leave {
animation: 0.5s fade-out;
}


Но это легче продемонстрировать с помощью это плунжер.



Есть идеи?



Примечание: чтобы быть ясным, желаемое поведение на плунжере связано с тем, что цветные квадраты всегда занимают одно и то же пространство, т. е. они сидят на одной линии, и кнопка не перемещается. Если возможно, я хотел бы исправить это без абсолютного позиционирования "bodges", поскольку фактическая страница, на которой я использую это, намного сложнее, чем демо подаренный.

619   2  

2 ответов:

Решение, которое я нашел для этого, состоит в том, чтобы дополнить чистую CSS-анимацию очень небольшим количеством JavaScript.

Чтобы подытожить проблему:

  • Входящий элемент добавляется в DOM с классом ng-enter одновременно с тем, как выходящему элементу присваивается класс ng-leave.

  • Хотя есть задержка анимации, входящий элемент все еще занимает пространство

Таким образом, этот фрагмент javascript берет элемент и добавляет ng-hide для продолжительность отпуска-анимация, удаление ее впоследствии.

.animation('.keyframe-fade', ['$timeout', function ($timeout){
  return {
    enter: function (element, done){

      // Add ng-hide for the duration of the leave animation.
      element.addClass('ng-hide');

      $timeout(function(){
        element.removeClass('ng-hide');
      }, 500)

      done();

    }
  }
}])

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

Улучшения / предложения приветствуются.

Вот оригинал плунькр с переменой.

Это ужасно, и для углового 2+, но просто для записи вот одна идея.

У меня есть два элемента button, один для того, когда у пользователя есть товары в корзине, и один для того, когда их нет.

Самый простой способ-это поместить position: relative на родительский DIV и position: absolute на обе кнопки. Главным недостатком является то, что родительский DIV приходится измерять вручную, и такие вещи, как центрирование, становятся сложнее.


Если намерение состоит в том, чтобы отложить добавление к DOM на основе Наблюдаемое значение, тогда я подумал: " почему бы просто не отложить наблюдаемое значение? ' который будет иметь тот же конечный эффект. Это должно быть сделано только тогда, когда переход от ложного > истинного, хотя, потому что вы только хотите скрыть его, когда он приходит в вид. Поэтому я воспользовался трубой, чтобы справиться с этим.

    <!-- This button for when item is IN the cart -->
    <button [@cartIconAnimation] *ngIf="showCartIcon | delayTrue | async">View Cart</button>

    <!-- This button for when item is NOT IN the cart -->
    <button [@cartIconAnimation] *ngIf="showCartIcon | complement | delayTrue | async">Add to Cart</button>

Это предполагает, что showCartIcon есть Observable<boolean>.

Тогда трубы выглядят следующим образом, и никакой задержки не требуется по вашим критериям анимации.

@Pipe({
    name: 'delayTrue'
})
export class DelayTruePipe implements PipeTransform {

    constructor() {}

    transform(value: Observable<any> | any, delay: number): Observable<any> {
        if (isObservable(value)) {
            return value.pipe(distinctUntilChanged(), debounce((show) => show ? timer(delay || 500) : empty()));
        } else {
            throw Error('Needs to be an observable');
        }
    }
}

@Pipe({
    name: 'complement'
})
export class ComplementPipe implements PipeTransform {

    constructor() {}

    transform(value: Observable<boolean> | any): Observable<any> {
        if (isObservable(value)) {
            return value.pipe(map(i => !i));
        } else {
            throw Error('Needs to be an observable');
        }
    }
}

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

Канал дополнения просто инвертирует логическое значение.

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

Comments

    Ничего не найдено.