Angular对话框ngModel绑定问题:需改为保存后同步UI而非实时同步
解决Angular对话框编辑时实时同步主UI的问题
这个问题的核心原因很直观:你直接把project对象传递给了对话框,而JavaScript里对象是引用传递的——对话框里的project和主界面的project指向的是同一个内存地址,所以你在对话框里用[(ngModel)]修改属性时,会实时同步到主界面,哪怕点击取消也没法回滚。
要实现「仅点击保存才同步修改」的效果,我们需要传递原对象的副本给对话框,修改副本不会影响原对象,只有在确认保存时,再把副本的更新同步回去。
步骤1:传递项目对象的副本给对话框
修改你打开对话框的代码,创建原project的拷贝,而不是直接传原对象:
openprojecteditdialog(project) { // 浅拷贝:适合没有嵌套对象的简单项目结构 const projectCopy = { ...project }; // 如果你的project有嵌套对象(比如子属性也是对象),需要用深拷贝: // const projectCopy = JSON.parse(JSON.stringify(project)); // 或者如果项目里用了lodash,可以用更可靠的深拷贝: // const projectCopy = _.cloneDeep(project); const dialogRef = this.dialog.open(ProjectEditDialogComponent, { data: projectCopy, disableClose: true }); // 订阅对话框关闭事件,处理保存逻辑 dialogRef.afterClosed().subscribe(updatedProject => { if (updatedProject) { // 这里把更新后的项目同步到store或主界面数据 this.store.dispatch(new UpsertProjectInternalAction(updatedProject)); } }); }
步骤2:修改对话框的保存与关闭逻辑
首先修正你对话框TS里的dialogRef类型错误(之前写成数组了),然后在保存时把修改后的副本返回给主组件:
export class ProjectEditDialogComponent implements OnInit { readonly projectsState = ProjectState; readonly projectsType = ProjectType; readonly level: string[] = []; working = false; newType = ''; newState = ''; constructor( public store: Store<ApplicationState>, // 修正类型:去掉数组符号[] public dialogRef: MatDialogRef<ProjectEditDialogComponent>, @Inject(MAT_DIALOG_DATA) public project: any) { } ngOnInit() { } save() { if (this.project.name.length > 0) { this.working = true; this.project.ProjectType = this.newType; this.project.ProjectState = this.newState; // 关闭对话框并返回修改后的项目副本 this.dialogRef.close(this.project); } } }
步骤3:取消按钮无需额外处理
你的取消按钮已经用了mat-dialog-close,点击它会直接关闭对话框,且不会返回任何结果——主组件的afterClosed()订阅里会收到undefined,这时我们不执行任何同步操作,原对象自然不会被修改。
这样修改后,对话框里的所有修改都只会作用于副本,只有当你点击「Save」时,才会把副本的更新同步到主UI和store,完美解决你的问题!
内容的提问来源于stack exchange,提问作者user9049996
相关产品推荐
相关产品推荐

