【问题标题】:How to close multiple dialog box using Angular如何使用Angular关闭多个对话框
【发布时间】:2020-07-29 17:23:52
【问题描述】:

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

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

所以,当我点击关闭按钮时,对话框关闭。

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

我的预期行为是关闭所有对话框。请帮我解决这个问题

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

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

【问题讨论】:

  • 查看角度材质对话框。您应该返回一个 dialogRef 实例,该实例也应该可以在您的对话框中注入。此 dialogRef 需要执行“关闭”,而不是 dialogService。或者您可以以某种方式在 dialogService 中创建一个对话框映射,并在您的 close 方法中传递一个参数来确定要关闭哪个对话框
  • @PierreDuc 能否请您更新 stackblitz 代码,以便我能清楚地了解。提前致谢。

标签: css angular typescript


【解决方案1】:

您需要管理所有模态组件,即在列表中,而不是将创建的模态组件分配给服务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 作为句柄,您还可以创建一些自定义对象来防止模态的调用者直接与组件交互。

【讨论】:

  • 感谢@Marc 的回答。你能告诉我在close方法的参数中传递什么引用吗?例如:如果我正在使用 ErrorModalComponent 那么我应该通过ref: ComponentRef&lt;ErrorModalComponent&gt;; 同时调用服务的关闭方法,如this.dialogServic.close(ref)
  • @asif905 这个想法是将您收到的句柄作为从 open() 方法的返回值传递:var ref = service.open(...); service.close(ref);
猜你喜欢
  • 2017-12-15
  • 2020-10-02
  • 2017-04-05
  • 1970-01-01
  • 2018-03-20
  • 2019-10-29
  • 2011-09-15
  • 2020-06-02
  • 2019-08-13
相关资源
最近更新 更多