我们有一个非常简单的组件,应该在: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;
}