Angular 动画 *ngIf + opacity 仅在一个方向有效
Angular animations *ngIf + opacity only works in one direction
我在使用 *ngIf 时遇到错误消息淡入淡出的问题。淡入效果很好,但淡出效果不佳。相反,文本只是消失了(就像设置为 display:none 一样),即使 *ngIf 在淡出完成之前不会生效。我曾尝试转换为使用字符串枚举和数值,但效果相同。我的动画配置有问题吗?
Linked stackblitz 使用的是 Angular 10,我使用的是 Angular 11.0.7(最新)。
https://stackblitz.com/edit/angular-ivy-bsuupd?file=src/app/form-error.component.ts
@Component({
selector: "app-form-error",
animations: [
trigger("fadeInOut", [
state("false", style({ opacity: 0 })),
state("true", style({ opacity: 1 })),
transition("true <=> false", animate(500))
])
],
template: `
<p>showError is {{ showError }}</p>
<p>fadeError is {{ fadeError }}</p>
<ng-container *ngIf="showError">
<h1 [@fadeInOut]="{ value: fadeError }">{{ errorText }}</h1>
</ng-container>
`
})
export class FormErrorComponent implements OnInit, OnChanges {
@Input() errorText: string;
showError: boolean = false;
fadeError: boolean = false;
constructor() {}
ngOnInit(): void {}
ngOnChanges(changes: SimpleChanges): void {
if (this.errorText) {
this.showError = true;
setTimeout(() => {
// lets fade in begin after ngIf takes effect (works fine)
this.fadeError = true;
});
} else {
this.fadeError = false; // this should start fade, but just hides the text immediately
setTimeout(() => {
// delays the ngIf until fade out is done
this.showError = false;
}, 500);
}
}
}
问题是您通过以下操作完全删除了文本:
this.errorMessage = null;
实际动画工作正常,问题是您要删除要显示的文本,所以您甚至看不到动画,因为文本会立即更改(变为无)。
你看看这个就明白我的意思了:
https://stackblitz.com/edit/angular-ivy-t3ft5x?file=src%2Fapp%2Fhello.component.ts
我只是像对待'test'
一样对待null
作为解决方案,您可以对文本使用 setter,并使用布尔标志作为:
errorTextToShow: string;
showErrorText: boolean;
@Input() set errorText(value: string) {
if(!!value){
this.errorTextToShow = value;
}
this.showErrorText = !!value;
}
并且在您的模板中有:
<h1 [@fadeInOut]="{ value: fadeError }">{{ errorTextToShow }}</h1>
这样就达到了你想要的效果,并且在设置input为null的时候不删除文字,淡出效果依然存在。
您可以在此处查看解决方案:
https://stackblitz.com/edit/angular-ivy-fwpgcw?file=src%2Fapp%2Fform-error.component.ts
我在使用 *ngIf 时遇到错误消息淡入淡出的问题。淡入效果很好,但淡出效果不佳。相反,文本只是消失了(就像设置为 display:none 一样),即使 *ngIf 在淡出完成之前不会生效。我曾尝试转换为使用字符串枚举和数值,但效果相同。我的动画配置有问题吗?
Linked stackblitz 使用的是 Angular 10,我使用的是 Angular 11.0.7(最新)。
https://stackblitz.com/edit/angular-ivy-bsuupd?file=src/app/form-error.component.ts
@Component({
selector: "app-form-error",
animations: [
trigger("fadeInOut", [
state("false", style({ opacity: 0 })),
state("true", style({ opacity: 1 })),
transition("true <=> false", animate(500))
])
],
template: `
<p>showError is {{ showError }}</p>
<p>fadeError is {{ fadeError }}</p>
<ng-container *ngIf="showError">
<h1 [@fadeInOut]="{ value: fadeError }">{{ errorText }}</h1>
</ng-container>
`
})
export class FormErrorComponent implements OnInit, OnChanges {
@Input() errorText: string;
showError: boolean = false;
fadeError: boolean = false;
constructor() {}
ngOnInit(): void {}
ngOnChanges(changes: SimpleChanges): void {
if (this.errorText) {
this.showError = true;
setTimeout(() => {
// lets fade in begin after ngIf takes effect (works fine)
this.fadeError = true;
});
} else {
this.fadeError = false; // this should start fade, but just hides the text immediately
setTimeout(() => {
// delays the ngIf until fade out is done
this.showError = false;
}, 500);
}
}
}
问题是您通过以下操作完全删除了文本:
this.errorMessage = null;
实际动画工作正常,问题是您要删除要显示的文本,所以您甚至看不到动画,因为文本会立即更改(变为无)。
你看看这个就明白我的意思了:
https://stackblitz.com/edit/angular-ivy-t3ft5x?file=src%2Fapp%2Fhello.component.ts
我只是像对待'test'
一样对待null
作为解决方案,您可以对文本使用 setter,并使用布尔标志作为:
errorTextToShow: string;
showErrorText: boolean;
@Input() set errorText(value: string) {
if(!!value){
this.errorTextToShow = value;
}
this.showErrorText = !!value;
}
并且在您的模板中有:
<h1 [@fadeInOut]="{ value: fadeError }">{{ errorTextToShow }}</h1>
这样就达到了你想要的效果,并且在设置input为null的时候不删除文字,淡出效果依然存在。
您可以在此处查看解决方案:
https://stackblitz.com/edit/angular-ivy-fwpgcw?file=src%2Fapp%2Fform-error.component.ts