我正在尝试将ng-animate
与ng-repeat
(以及ng-show
)一起淡出旧内容并将其替换为新内容。
我遇到的问题是在remove
和add
动画期间,要添加的元素和要删除的元素都有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'的情况下解决这个问题,因为我使用它的实际页面比给出的演示要复杂得多。
答案 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>
这假定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
,我只会做这样的事情。