Angular页面导航时whatsAppChildClientNumbers数据填充不稳定问题
问题分析
你的问题核心是异步操作顺序不匹配以及组件复用导致数据未重新加载:
getAllClientWhatsAppNumbers是异步请求,在constructor中调用时,返回的whatsAppClientNumbers可能还未就绪,而getAllChildClientWhatsAppNumbers在loadSystemData中同步执行,此时遍历空数组自然无法填充数据。- Angular路由导航时若组件被复用(比如路由参数变化但组件实例保留),
constructor和ngOnInit不会重复执行,导致数据不会重新加载。 getAllChildClientWhatsAppNumbers中未做空值防护,一旦某个属性未初始化会直接中断执行。
解决方案
1. 调整异步逻辑顺序,确保依赖数据就绪后再处理
使用RxJS的combineLatest组合异步流,保证currentUser和whatsAppClientNumbers都加载完成后,再执行后续数据处理逻辑。
2. 处理组件复用场景
监听路由参数变化,触发数据刷新;同时在组件销毁时清理所有订阅,避免内存泄漏。
3. 添加空值防护
在属性访问时使用可选链操作符?.,避免空指针异常。
修改后的代码示例
import { combineLatest, Subscription } from 'rxjs'; import { ActivatedRoute } from '@angular/router'; // 组件属性添加路由订阅变量 routeSubscription?: Subscription; constructor( private whatsAppSendReceiveMessagesService: WhatsAppSendReceiveMessagesService, private whatsAppClientNumberService: WhatsAppClientNumberService, private whatsAppNumberService: WhatsAppNumberService, private clientService: ClientService, private helperService: HelperService, private systemUserService: SystemUserService, private reportService: ReportService, private route: ActivatedRoute // 注入路由服务 ) { this.whatsAppSendReceiveMessages = []; this.whatsAppSendReceiveMessage = new WhatsAppSendReceiveMessages; this.pageSize = 5; this.currentPage = 0; const currentDate = new Date(); for (let i = 0; i < 12; i++) { this.availableMonthYears.push(new Date(currentDate.getFullYear(), currentDate.getMonth() - i, 1)); } this.selectedMonthYear = new Date(currentDate.getFullYear(), currentDate.getMonth(), 1); // 移除constructor中的getAllClientWhatsAppNumbers调用 } ngOnInit(): void { this.refreshData(); this.onMonthYearSelected(); // 监听路由参数变化,组件复用时自动刷新数据 this.routeSubscription = this.route.paramMap.subscribe(() => { this.refreshData(); }); } // 统一数据刷新入口 refreshData() { this.loadSystemData(); } loadSystemData() { // 组合两个异步流,确保两者都返回数据后再处理 combineLatest([ this.systemUserService.getCurrentLoginUser(), this.whatsAppClientNumberService.getAllWhatsAppClientNumbers() ]).subscribe(([currentUser, whatsAppClientNumbers]) => { this.currentUser = currentUser; this.whatsAppClientNumbers = whatsAppClientNumbers; this.updateFilteredWhatsAppNumbers(); if (this.currentUser) { this.currentUser.role === 'Sysadmin' ? this.getAllClients() : this.getCurrentClient(); this.getAllChildClientWhatsAppNumbers(); this.getAllParentClientNumbers(); this.searchWhatsAppSendReceiveMessages(); } }, error => { this.helperService.showNotification('top', 'right', 'danger', error.error ? error.error : "Something went wrong"); }); } // 增强空值防护的getAllChildClientWhatsAppNumbers getAllChildClientWhatsAppNumbers() { this.whatsAppChildClientNumbers = []; this.whatsAppClientNumbers?.forEach(whatsappClientNumber => { if (whatsappClientNumber?.clientConfig?.clientRef === this.currentUser?.client?.clientRef) { this.whatsAppChildClientNumbers.push(whatsappClientNumber?.whatsAppNumber?.number); } }); } // 组件销毁时清理所有订阅 ngOnDestroy() { this.currentUserSubscription?.unsubscribe(); this.clientSubscription?.unsubscribe(); this.getWhatsAppClientNumberSubscription?.unsubscribe(); this.routeSubscription?.unsubscribe(); }
模板部分无需修改
原模板的逻辑是正确的,只要whatsAppChildClientNumbers能被正确填充,mat-option就会正常渲染。
内容的提问来源于stack exchange,提问作者M2bar
相关产品推荐
相关产品推荐

