我制作了一个手风琴组件(Angular18),其主体内容延迟加载,并且打开和关闭的动画流畅。 因此,当我从内部切换它时(通过单击标题),它工作得很好, 但是当我从外面切换它时 - 它不能顺利打开(但可以顺利关闭)。
这是堆栈闪电战: https://stackblitz.com/edit/stackblitz-starters-rjsmkv
这种行为有什么意义?我对 Angular 动画很陌生..
尝试用输入替换模型 - 同样的事情。由于内容大小不同,具有 maxheight 的 CSS 动画不够好。
信号的
toObservable
,似乎重新触发了delayedIsOpen
的流,这反过来又重新创建了if条件@if (delayedIsOpen | async) {
内的元素,并再次创建了元素<ng-container *ngTemplateOutlet="accordionBodyRef" />
,这似乎弄乱了动画。
我不确定您为什么需要这种延迟,但消除延迟可以解决问题。
<div
class="accordion"
[ngStyle]="{ '--transiton-time': transitionTime + 'ms' }"
>
<div class="accordion-head">
<div class="top-side top-side_left" (click)="toggle()">
<ng-content select="[topLeft]" />
</div>
</div>
<div
class="main-content"
[@content]="
isOpen()
? { value: 'visible', params: { transitionParams } }
: { value: 'hidden', params: { transitionParams } }
"
>
<ng-container *ngTemplateOutlet="accordionBodyRef" />
</div>
</div>
import {
animate,
state,
style,
transition,
trigger,
} from '@angular/animations';
import {
ChangeDetectionStrategy,
Component,
input,
model,
ContentChild,
TemplateRef,
} from '@angular/core';
import { toObservable } from '@angular/core/rxjs-interop';
import { delay, of, switchMap } from 'rxjs';
@Component({
selector: 'accordion',
templateUrl: './accordion.component.html',
styleUrl: './accordion.component.scss',
changeDetection: ChangeDetectionStrategy.OnPush,
animations: [
trigger('content', [
state(
'hidden',
style({
height: '0',
visibility: 'hidden',
})
),
state(
'visible',
style({
height: '*',
visibility: 'visible',
})
),
transition('visible <=> hidden', [animate('{{transitionParams}}')]),
transition('void => *', animate(0)),
]),
],
})
export class AccordionComponent {
isOpen = model<boolean>(false);
transitionTime = 500;
transitionParams = `${this.transitionTime}ms linear`;
// delayedIsOpen = toObservable(this.isOpen)
// .pipe
// // switchMap((open) =>
// // open ? of(open) : of(open).pipe(delay(this.transitionTime))
// // )
// ();
@ContentChild('accordionBody', { read: TemplateRef })
accordionBodyRef: TemplateRef<unknown> | null = null;
toggle(): void {
this.isOpen.update((value) => !value);
}
}