Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
495 views
in Technique[技术] by (71.8m points)

Angular animations *ngIf + opacity only works in one direction

I'm having an issue with fading in and out an error message while also using *ngIf. The fade-in works fine, but the fade out does not work. Instead, the text just disappears (as if set to display:none), even though the *ngIf does not take effect until the fade out is complete. I have tried converting to use string enumerations and numeric values but get the same effect. Is there an issue with my animations configuration?

Linked stackblitz is using Angular 10, I'm on Angular 11.0.7 (latest).

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);
    }
  }
}
question from:https://stackoverflow.com/questions/65646139/angular-animations-ngif-opacity-only-works-in-one-direction

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The problem is that you are removing the text altogether by doing:

 this.errorMessage = null;

The actual animation is working fine, the issue is that you are removing the text to be displayed, so you don't even see the animation as the text changes immediately (into nothing).

You can see what I mean by looking at this:
https://stackblitz.com/edit/angular-ivy-t3ft5x?file=src%2Fapp%2Fhello.component.ts

I am simply treating 'test' as you're treating null


As a solution you can use a setter for the text and a boolean flag as:

  errorTextToShow: string;
  showErrorText: boolean;
  @Input() set errorText(value: string) {
    if(!!value){
      this.errorTextToShow = value;
    }
    this.showErrorText = !!value;
  }

and in your template have:

  <h1 [@fadeInOut]="{ value: fadeError }">{{ errorTextToShow }}</h1>

In this way to achieve what you wanted and don't delete the text when setting the input to null so that the fade-out effect can still be present.

You can check out the solution here:
https://stackblitz.com/edit/angular-ivy-fwpgcw?file=src%2Fapp%2Fform-error.component.ts


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...