如何使用Angular 12中的动画设置:离开事件上的:host元素的动画



我们有一个非常简单的组件,应该在:enter:leave事件中淡出:

import { Component, HostBinding } from '@angular/core';
import { animate, style, transition, trigger } from '@angular/animations';
@Component({
  selector: 'app-test',
  templateUrl: './test.component.html',
  styleUrls: ['./test.component.scss'],
  animations: [
    trigger('host', [
      transition(':enter', [
        style({ opacity: 0 }),
        animate('240ms linear', style({ opacity: 1 })),
      ]),
      transition(':leave', [
        style({ opacity: 1 }),
        animate('240ms linear', style({ opacity: 0 })),
      ])
    ]),
  ]
})
export class TestComponent {
  @HostBinding('@host') host() {
    return true;
  }
}

组件是这样使用的:

<app-test *ngIf="someBoolean"></app-test>

现在:enter上的动画确实运行了。但是,当组件被移除时(变量someBoolean变为false(,该元素并没有淡出。

缺少什么?

在父组件中使用*ngIf会使元素动画不注册

让我们关注发生了什么

  • someBoolean=>从false开始
  • <app-test *ngIf='someBoolean'></app-test>不存在
  • CCD_ 10=>true
  • 加载<app-test></app-test>
  • 加载动画。。。等一下,刚才发生了什么事?我们加载了app-test,然后加载了动画!但是动画是在什么时候触发的呢?这个问题的答案是为什么你的动画没有被触发。我们需要重新注册动画,然后才能应用它们

因此,让我们停止上述事件序列并重试步骤

  • someBoolean=>从false开始
  • 创建<app-test [shown]='someBoolean'></app-test>
  • 注册动画
  • CCD_ 17=>true
  • <app-test></app-test>的显示内容
  • 动画在注册后开始播放

好的,现在我们已经知道了这将如何工作,让我们开始编码

组件使用

`<app-test [shown]='someBoolean'></app-test>`

组件TS文件

@Component({
  selector: "app-test",
  templateUrl: "./test.component.html",
  styleUrls: ["./test.component.css"],
  animations: [
    trigger("host", [
      transition(":enter", [
        style({ opacity: 0 }),
        animate("240ms linear", style({ opacity: 1 }))
      ]),
      transition(":leave", [
        style({ opacity: 1 }),
        animate("240ms linear", style({ opacity: 0 }))
      ])
    ])
  ]
})
export class TestComponent implements OnInit {
  // @HostBinding("@host") host() {
  //   return true;
  // }
  @Input() shown;
  constructor() {}
  ngOnInit() {}
}

我已经评论了@HostBinding,因为我没有看到它是如何在这里实现的。

最后我们可以将*ngIf应用于组件的内容中

<div *ngIf='shown'>
  <!-- Animation works! -->
</div>

请参阅此处的演示

这能解决问题吗?

import {
  animate,
  state,
  style,
  transition,
  trigger,
} from '@angular/animations';
import { Component } from '@angular/core';
@Component({
  selector: 'parent',
  animations: [
    trigger('toggle', [
      state('true', style({ overflow: 'hidden', opacity: '*' })),
      state('false', style({ overflow: 'hidden', opacity: 0, height: 0 })),
      transition('true => false', animate('400ms ease-in-out')),
      transition('false => true', animate('400ms ease-in-out')),
    ]),
  ],
  template: `
    <button (click)="someBoolean = !someBoolean">CLICK</button>
    <div [@toggle]="someBoolean">
      <app-test></app-test>
    </div>
  `,
})
export class ParentComponent {
  someBoolean = false;
}

最新更新