3

我正在尝试使用ng-animate( ng-repeatand ng-show) 淡出旧内容并将其替换为新内容。

我遇到的问题是,在removeadd动画期间,添加的元素和删除的元素都有display:block.

我想我可以通过在 CSS 中使用 an 来避免这种情况animation-delay,但这只会延迟淡入淡出,而不是添加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;
}

但是用这个 plunkr更容易演示。

有任何想法吗?

注意:需要明确的是,plunkr 链接的期望行为是彩色方块总是占据相同的空间,即它们位于同一行并且按钮不移动。如果可能的话,我想在没有绝对定位“bodges”的情况下解决这个问题,因为我使用它的实际页面比给出的演示要复杂得多。

4

2 回答 2

2

我为此找到的解决方案是使用非常少量的 JavaScript 来增强纯 CSS 动画。

总结一下问题:

  • 进入元素与ng-enter类一起添加到 DOM 中,同时离开元素被赋予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();

    }
  }
}])

持续时间在这里是硬编码的,但我看不出有任何理由不能从元素中获取它。

欢迎改进/建议。

这是更改后的原始plunkr

于 2014-03-03T09:52:27.610 回答
1

这太糟糕了,对于 Angular 2+,但只是为了记录,这里有一个想法。

我有两个button元素,一个是当用户的购物车中有商品时,一个是当他们没有时。

到目前为止,最简单的方法是放在position: relative父 DIV 和position: absolute两个按钮上。主要缺点是必须手动调整父 DIV 的大小,并且诸如居中之类的事情变得更加棘手。


如果意图是基于 Observable 值延迟添加到 DOM,那么我想'为什么不只是延迟 observable 值呢?' 这将具有相同的最终效果。仅当转换从 false > true 时才需要执行此操作,因为您只想在它出现时隐藏。所以我用一个管道来处理这个。

    <!-- 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>

这假设showCartIconObservable<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');
        }
    }
}

注意:管道使用的延迟必须大于上一个项目消失的时间,否则你会遇到同样的问题。

补码管道只是反转布尔值。

This solution works, but it's hacky and the timing might be harder to get wrong and there may be race conditions as two different browser timers fire off at the same time. I'd only do something like this if you really can't use position: absolute.

于 2018-06-12T03:33:59.063 回答