gpt4 book ai didi

Angular 5 动画 : How to work with :leave transition while the component is removed from DOM

转载 作者:行者123 更新时间:2023-12-02 11:22:44 24 4
gpt4 key购买 nike

我们一直在项目中使用 @ng-bootstrap/ng-bootstrap 库来实现某些行为/组件,例如 Modal。最近我想消除这种依赖性并使用 Angular 实现引导模式行为。这实际上很容易。让我简短地告诉您它是如何工作的:

我有一个模态服务和一个模态组件。 Service 通过 ComponentFactoryResolver 动态创建模态组件(详情见 in this SO post )并添加到 DOM 中。通过关闭模态,模态只是调用从服务定义的回调函数,这只是销毁组件,从 DOM 中删除。

所以:我这个模态组件有 2 个动画状态,进入和离开。输入效果很好。一旦组件出现在 dom 中,预定义的 :enter 状态就会被触发,我的动画就会开始工作。但是 :leave 却没有。

这正是关闭模态框的工作原理:模态框打开,您单击关闭按钮或模态背景上的任何其他位置。这只是调用 close 函数,该函数被定义为输入,并在创建期间从服务给出。

@Input() closeCallback: Function;

服务只是从 DOM 中删除组件。

由于单击关闭按钮后组件就会被删除,因此我认为动画没有所需的时间。所以 :leave 不起作用。

我想在关闭时设置超时(延迟),并手动触发动画,但由于我想使用预定义的行为:enter和:leave,我无法弄清楚它是如何实现的。那么我怎样才能让我的离开动画发挥作用呢? (有或没有:leave)

服务代码:

@Injectable()
export class ModalService implements OnDestroy {

private renderer: Renderer2;
private componentRef: ComponentRef<ModalComponent>;

constructor(private rendererFactory: RendererFactory2,
private componentFactoryResolver: ComponentFactoryResolver,
private appRef: ApplicationRef,
private injector: Injector) {
this.renderer = rendererFactory.createRenderer(null, null);
}

ngOnDestroy() {
this.componentRef.destroy();
}

open(content: string, titel: string, primaryButtonLabel: string, secondaryButtonLabel?: string, primaryButtonCallback?: Function, secondaryButtonCallback?: Function) {
// 1. Create a component reference from the component
this.componentRef = this.componentFactoryResolver
.resolveComponentFactory(ModalComponent)
.create(this.injector);

this.componentRef.instance.content = content;
this.componentRef.instance.titel = titel;
this.componentRef.instance.primaryButtonLabel = primaryButtonLabel;
this.componentRef.instance.secondaryButtonLabel = secondaryButtonLabel;
this.componentRef.instance.primaryButtonCallback = primaryButtonCallback;
this.componentRef.instance.secondaryButtonCallback = secondaryButtonCallback;
this.componentRef.instance.closeCallback = (() => {
this.close();
});

// 2. Attach component to the appRef so that it's inside the ng component tree
this.appRef.attachView(this.componentRef.hostView);

// 3. Get DOM element from component
const domElem = (this.componentRef.hostView as EmbeddedViewRef<any>)
.rootNodes[0] as HTMLElement;

// 4. Append DOM element to the body
this.renderer.appendChild(document.body, domElem);
this.renderer.addClass(document.body, 'modal-open');
}

close() {
this.renderer.removeClass(document.body, 'modal-open');
this.appRef.detachView(this.componentRef.hostView);
this.componentRef.destroy();
}
}

模态组件.ts:

@Component({
selector: '[modal]',
templateUrl: './modal.component.html',
styleUrls: ['./modal.component.scss'],
animations: [
trigger('modalSlideInOut', [
transition(':enter', [
style({opacity: 0, transform: 'translateY(-100%)'}),
animate('0.3s ease-in', style({'opacity': '1', transform: 'translateY(0%)'}))
]) ,
transition(':leave', [
style({opacity: 1, transform: 'translateY(0%)'}),
animate('0.3s ease-out', style({'opacity': '0', transform: 'translateY(-100%)'}))
])
])
]
})
export class ModalComponent implements AfterViewInit {

....
@Input() closeCallback: Function;

constructor() { }

close() {
this.closeCallback();
}
}

Modal-HTML 不是很相关,但你可以像这样想象:

<div [@modalSlideInOut] role="document" class="modal-dialog">
<div ....
<button (click)="close()">
CLOSE
</button>

...
</div>
</div>

最佳答案

我今天遇到了类似的问题,我找到的解决方案是简单地将动画绑定(bind)到 Host 组件本身:

@HostBinding('@modalSlideInOut')

这样,您就不必对动画计时进行任何欺骗。当您调用 destroy 时,Angular 知道组件即将消失,因此它会为您处理它,就像您在组件上调用 ngIf 一样。

关于Angular 5 动画 : How to work with :leave transition while the component is removed from DOM,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51589893/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com