Angular中MAT_DIALOG_DATA首次点击无数据二次点击正常问题
问题根源分析
你遇到的这个问题是异步操作时序错误导致的:在OnEdit方法中,你先发起了getUsersList的HTTP请求,但subscribe回调是异步执行的——也就是说,当你执行const userToUpdate = this.UsersTest.find(c => c.id === id);这行代码时,HTTP请求还没返回结果,UsersTest还是空数组,自然找不到对应的用户,所以弹窗接收的data是undefined。而第二次点击时,UsersTest已经被第一次请求的结果填充,所以能正常找到用户。
另外还有个冗余点:你已经在ngOnInit里把活跃用户加载到users数组里了,完全没必要在点击Details时重新请求一遍用户列表,直接从已有的users数组里查找即可,既节省API请求,又能彻底避免异步问题。
修复方案
方案一:优化现有逻辑(把查找用户放到异步回调内)
如果一定要重新请求用户列表(比如担心数据过期),请把弹窗打开的逻辑放到subscribe的回调函数里,确保拿到数据后再处理:
OnEdit(id: number) { this.isPopupOpened = true; this.userService .getUsersList() .pipe(map(arr => arr.filter(r => r.active == true))) .subscribe(result => { this.UsersTest = result; // 这里才是拿到数据后的正确时机 const userToUpdate = this.UsersTest.find(c => c.id === id); if (userToUpdate) { // 增加空值判断,避免弹窗传入undefined const dialogRef = this.matdialog.open(UserDetailsComponent, { data: userToUpdate }); dialogRef.afterClosed().subscribe(result => { this.isPopupOpened = false; this.reloadData(); }); } else { console.warn(`未找到ID为${id}的用户`); } }); }
方案二:直接使用已加载的users数组(推荐)
既然ngOnInit已经把活跃用户加载到users数组里了,直接从这里查找用户,完全避免异步问题:
OnEdit(id: number) { this.isPopupOpened = true; // 直接从已有的users数组查找,无需重复请求API const userToUpdate = this.users.find(c => c.id === id); if (userToUpdate) { const dialogRef = this.matdialog.open(UserDetailsComponent, { data: userToUpdate }); dialogRef.afterClosed().subscribe(result => { this.isPopupOpened = false; this.reloadData(); }); } else { console.warn(`未找到ID为${id}的用户`); } }
额外优化:弹窗组件的空值防护
为了避免弹窗组件因为data为undefined报错,建议在UserDetailsComponent的ngOnInit里增加空值判断:
ngOnInit() { // 如果data为空,初始化默认值 const defaultData = { id: null, active: true, nom: '', prenom: '', email: '', role: '' }; const userData = this.data || defaultData; this._contactForm = this._formBuilder.group({ id: [userData.id], active: [userData.active, [Validators.required]], nom: [userData.nom, [Validators.required]], prenom: [userData.prenom, [Validators.required]], email: [userData.email, [Validators.required]], role: [userData.role, [Validators.required]] }); }
这样即使意外传入undefined,弹窗也不会直接报错,提升了组件的健壮性。
内容的提问来源于stack exchange,提问作者Mensi98
相关产品推荐
相关产品推荐

