我有一个扩展面板组件。这个组件本身工作得很好。这是它的代码。
<div class="container">
<div class="header" (click)="toggleSelf()">
<div class="header--content">
{{ header }}
</div>
<div class="header--action" [ngClass]="{ rotated: !isClosed }">
<mat-icon svgIcon="chevron-down-filled"></mat-icon>
</div>
</div>
<div class="content" *ngIf="!isClosed" [@expand]>
<div class="content-wrapper">
<ng-content></ng-content>
</div>
</div>
</div>类型标
import { Component, Input } from '@angular/core';
import { trigger, transition, style, animate } from '@angular/animations';
@Component({
selector: 'sky-expansion-panel',
templateUrl: './expansion-panel.component.html',
styleUrls: ['../../../../scss/components/accordion.scss'],
animations: [
trigger('expand', [
transition(':enter', [
style({
height: '0',
opacity: 0,
overflow: 'hidden'
}),
animate(
'500ms cubic-bezier(1, .14, .69, .05)',
style({
height: '*',
opacity: 1,
overflow: 'visible'
})
)
]),
transition(':leave', [
style({
height: '*',
opacity: 1,
overflow: 'hidden'
}),
animate(
'500ms cubic-bezier(1, .14, .69, .05)',
style({
height: '0',
opacity: 0,
overflow: 'hidden'
})
)
])
])
]
})
export class SkyExpansionPanelComponent {
@Input() header: string;
@Input() isClosed = true;
public toggleSelf(): void {
this.isClosed = !this.isClosed;
}
}实现HTML示例
<filter-panel *ngIf="toggleLogic()"
<sky-accordion>
<sky-expansion-panel header="General" [isClosed]="filterStatus.generalTabOpen">
//irrelevant content
</sky-expansion-panel>
</sky-accordion>
</filter-panel>当我把这个动画引入一个过滤面板时,我开始遇到麻烦,它也是隐藏的,并且用*ngIf显示。
我已经发现,当父组件隐藏扩展面板(通过隐藏过滤器面板)时,它在技术上触发: that动画,并在组件被破坏之前快速地应用样式。
通常情况下,如果我们希望扩展面板恢复到封闭状态,这不会是个问题。我们跟踪它是开着还是关着的。当打开过滤器面板时,扩展面板会记住正确的状态(通过isClosed输入)。
问题是,尽管内容是在DOM上呈现的,但出于某种原因,来自封闭状态的内联样式被应用到扩展面板中。更奇怪的是,你通常可以在开发工具中看到这样的东西-
<div class="content" style="height: 0; opacity: 0; overflow: hidden;">如果您在打开状态下用展开面板关闭过滤器,然后重新打开它们,它实际上在dev tools中会出现如下所示。
<div class="content" style>基本上,所有的工作正常,除了动画是内联风格,它不应该内联。
为了纠正这个问题,我尝试用状态方法来做动画。下面的语法可能会很混乱,因为我是从内存中输入的,但是您得到了它的要点。
状态逼近
animations: [
trigger('expand', [
state('closed', [
style({
height: '0',
opacity: 0,
overflow: 'hidden'
}),
]),
state('open', [
style({
height: '*',
opacity: 1,
overflow: 'visible'
})
]),
transition('closed => open', [
animate( '500ms cubic-bezier(1, .14, .69, .05)')
]),
transition('open => void', [
animate('500ms cubic-bezier(1, .14, .69, .05)')
]),
transition('void => open', [
animate('500ms cubic-bezier(1, .14, .69, .05)')
])
])
]状态逼近表达式
<div class="content" *ngIf="!isClosed" [@expand]="isClosed ? closed : open">这也没有产生任何不同的结果。此时,我打算尝试在ngOnInit中设置ngOnInit的值,希望触发器会改变,但发现扩展面板中的ngOnInit和其他生命周期挂钩在页面加载时触发一次,即使过滤器甚至不在DOM上。是否有一种方法可以在每次向DOM中添加或移除它们时强制它们触发,以便我可以尝试更新这个动画的状态?
还是有人对我的问题有别的建议?现在,我只是删除离开动画,但理想情况下,我保留动画。
除了页面加载时,扩展面板中没有生命周期挂钩。
发布于 2021-06-08 17:04:44
奇怪的是,这种方法有什么不同吗?
<ng-container *ngIf="!isClosed">
<div class="content" [@expand]>
<div class="content-wrapper">
<ng-content></ng-content>
</div>
</div>
<ng-container>import { Component, Input, OnInit, OnDestroy } from '@angular/core';
export class SkyExpansionPanelComponent implements onInit, onDestroy{
@Input() header: string;
@Input() isClosed = true;
public toggleSelf(): void {
this.isClosed = !this.isClosed;
}
ngOnInit() {
// gets fired every time the component is added
}
ngOnDestroy() {
// gets fired every time the component is removed
}
}https://stackoverflow.com/questions/67891375
复制相似问题