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