在Angular Material中处理对话框/模态的正确方法是什么?

时间:2019-12-18 18:34:22

标签: angular dialog angular-material ngrx

我正在使用AngularAngular Material构建应用程序。应用中的某些操作必须在模态/对话框中执行。因此,我使用MatDialog

例如,假设我必须删除user,并且这应该在对话框中发生。最简单的实现如下所示:

解决方案1 ​​

deleteUser(user: User): void {
    const deleteUserDialogRef = this._dialog
        .open(DeleteUserDialogComponent, { data: { user } });

    deleteUserDialogRef
        .afterClosed()
        .subscribe((confirmed: boolean) => {
            if (confirmed) {
                this.usersService.delete(user.id);
            }
        });
}

解决方案2

现在,假设您想在对话框中安装一个加载微调器,以指示该操作仍在进行中。为了使对话框简单,您必须牺牲实际上已打开对话框的父组件。

首先,您必须通过EventEmitter发出事件,而不是在用户单击确认按钮时实际上关闭对话框。然后,您必须从父级那里监听该事件:

// ..
deleteUserDialogRef
    .componentInstance
    .confirmed
    .subscribe(() => this.usersService.delete(user.id))

并且要更改对话框的loading输入,您必须执行以下操作:

this.usersService
    .deleteUserLoading$
    .subscribe(loading => {
        deleteUserDialogRef
            .componentInstance
            .data
            .loading = loading;
    });

这并不难实现,但是想像一下,如果您必须对所有CRUD操作都执行相同的操作。您的对话框将是简单的(和演示性的),但是您的容器组件将变得庞大,并且可能难以阅读和管理。

解决方案3

您可以尝试使对话框变得聪明,而不是遵循解决方案2 。您可以直接在模式中注入服务/商店并处理请求,在内部加载状态。但是,缺点是您必须通过服务/存储选择器注入用户数据,因为您不应在智能组件中使用@Inputs()。

因此,您必须执行以下操作:

// Container
// ..
deleteUser(user: User): void {
    this.usersService.selectUser(user);

    const deleteUserDialogRef = this._dialog.open(DeleteUserDialogComponent);

    deleteUserDialogRef
        .afterClosed()
        .subscribe(() => this.usersService.deselectUser());
}

// Dialog
// ..
this.user$ = this.usersService.selectedUser$;

所以,我的问题是设计此解决方案的正确方法是什么-解决方案2 解决方案3 还是其他?

1 个答案:

答案 0 :(得分:0)

对我来说,解决方案是使用NgRx效果做到这一点。

因为它对组件隐藏了表单逻辑处理,并且可以在多个组件中使用相同的对话框。形式本身保持“哑巴”,逻辑进入效果。

FocusIn

更多信息,Start using ngrx/effects for this