angular - 在 Angular Material 中处理对话框/模态的正确方法是什么?
问题描述
我正在使用Angular和Angular Material构建应用程序。应用程序中的某些操作必须在模式/对话框中执行。出于这个原因,我使用MatDialog
.
例如,假设我必须删除 auser
并且这应该发生在对话框中。最简单的实现如下所示:
解决方案 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还是别的什么?
解决方案
对我来说,解决方案是使用 NgRx Effects 来做到这一点。
因为它对组件隐藏了表单逻辑处理,并且可以从多个组件中使用同一个对话框。表单本身保持“哑”,逻辑进入效果。
@Effect()
openDialog = this.actions.pipe(
ofType(LoginActionTypes.OpenLoginDialog),
exhaustMap(_ => {
let dialogRef = this.dialog.open(LoginDialog);
return dialogRef.afterClosed();
}),
map((result: any) => {
if (result === undefined) {
return new CloseDialog();
}
return new LoginDialogSuccess(result);
}),
);
推荐阅读
- python - Wagtail:动态选择具有默认值的模板
- sql - 错误 tcNull Golang HanadB
- scikit-learn - 潜在语义分析:如何选择组件号来执行截断SVD
- python - 绘制共享 x 值的三个函数
- linux - 如何在linux中的给定时间关闭firefox?
- javascript - react-native 构建错误(开发服务器返回响应错误代码:500)
- ios - 使用 Kingfisher 取消单个图像下载
- sql - 指定两个排序索引?
- email - Google Analytics(分析)测量协议命中 URL 中的 Mailchimp 合并标签
- ios - 线程 1:EXC_BREAKPOINT(代码=1,子代码=0x18407cb5c)