首页 > 解决方案 > 如何使用Angular关闭多个对话框

问题描述

我有一个正在运行的 Angular 9 应用程序,并且我创建了自定义对话框。我还使用 ComponentFactoryResolver 来动态加载组件。

我的自定义对话框如下所示:

在此处输入图像描述

因此,当我单击关闭按钮时,对话框关闭。

根据当前的实现,如果我在屏幕上打开多个对话框,那么我只能通过单击关闭按钮关闭最后打开的对话框。

我的预期行为是关闭所有对话框。请帮助我

Stackblitz 演示: https ://stackblitz.com/edit/dialog-box-overlay

注意:在这个 stackblitz 演示中,一个模态在另一个模态的顶部打开,因为我没有修改 css。所以,请关注 Modal 名称来了解打开的是哪个 modal

标签: cssangulartypescript

解决方案


无需将创建的模态组件分配给服务dcRef属性,您需要管理所有模态组件,即在列表中。您的服务open()方法

open(component: Type<any>, modalName: string) {
    const factory = this.componentFactoryResolver.resolveComponentFactory(DialogComponent);
    this.dcRef = factory.create(this.injector);
    ...
    return this.dcRef;
}

返回组件引用。您可以从调用者管理此引用并将其作为参数传递给您的close()方法。当所有组件引用都由服务管理时,您还可以“批量关闭”所有模式(请参阅 参考资料closeAll()):

@Injectable()
export class DialogService {

    refs: ComponentRef<DialogComponent>[] = [];

    constructor(private componentFactoryResolver: ComponentFactoryResolver,
        private applicationRef: ApplicationRef,
        private injector: Injector
    ) { }

    open(component: Type<any>, modalName: string) {
        const factory = this.componentFactoryResolver.resolveComponentFactory(DialogComponent);
        var ref = factory.create(this.injector);
        this.applicationRef.attachView(ref.hostView);
        const domElement = (ref.hostView as EmbeddedViewRef<any>).rootNodes[0] as HTMLElement;
        document.body.appendChild(domElement);
        ref.changeDetectorRef.detectChanges();
        ref.instance.open(component, modalName);
        this.refs.push(ref);
        return ref;
    }

    close(ref) {        
        this.applicationRef.detachView(ref.hostView);
        ref.instance.close();
        ref.destroy();
        // Remove ref from a list managed by the service
        var i = this.refs.indexOf(ref);
        this.refs.splice(i, 1);
    }

    closeAll()
    {       
        this.refs.forEach(r => this.close(r));
    }
}

这未经测试,可能需要调整,但您应该明白这一点。除了将ComponentRef用作句柄之外,您还可以创建一些自定义对象来防止模态的调用者直接与组件交互。


推荐阅读