ng-animate:仅在动画延迟后添加到dom

时间:2014-02-03 23:06:54

标签: angularjs ng-animate angular-transitions

我正在尝试将ng-animateng-repeat(以及ng-show)一起淡出旧内容并将其替换为新内容。

我遇到的问题是在removeadd动画期间,要添加的元素和要删除的元素都有display:block。< / p>

我认为我可以通过在CSS中使用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;
}

但使用this plunkr进行演示更容易。

有什么想法吗?

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

2 个答案:

答案 0 :(得分:2)

我找到的解决方案是使用极少量的JavaScript来增加纯CSS动画。

总结问题:

  • 在将离开元素赋予ng-enter类的同时,将输入元素添加到具有ng-leave类的DOM中。

  • 虽然有动画延迟,但输入元素仍会占用空间

因此,这段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 with the change

答案 1 :(得分:0)

这很糟糕,对于Angular 2+而言,只是为了记录这里的一个想法。

我有两个button元素,一个用于用户在购物车中有商品的元素,另一个用于他们不在的时候。

到目前为止,最简单的方法是将position: relative放在父DIV上,将position: absolute放在两个按钮上。主要的缺点是父DIV必须手动调整大小,并且像居中这样的东西变得更加棘手。

如果意图是根据Observable值延迟添加DOM,那么我认为&#39; 为什么不延迟可观察的值?&#39;这将产生相同的最终效果。只有当转换来自false时,才需要这样做。是的,因为您只想在进入视图时隐藏它。所以我用一根烟斗来处理这件事。

    <!-- 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');
        }
    }
}

注意:管道使用的延迟必须大于上一项消失所需的时间,否则您将遇到同样的问题。

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

这个解决方案有效,但它很糟糕,时间可能更难以出错,并且可能存在竞争条件,因为两个不同的浏览器计时器同时启动。如果你真的不能使用position: absolute,我只会做这样的事情。