投资组合搜索出错时‘选择确认’模态框异常显示问题
问题描述
在投资组合选择页面,支持通过账号或名称搜索:
- 输入正确账号
979-9638403-03并点击Search,能正常显示包含客户数据的模态框; - 输入错误账号(如
123-4)时,系统先显示输入错误的模态框,但关闭该模态框后,Selection confirmation模态框会异常弹出,而错误场景下此模态框本不应出现。
问题分析
当前代码的核心问题是:submit方法一开始就实例化了SelectPortfolioResultModalComponent(即包含选择确认的模态框),无论后续API返回是否为错误结果,这个模态框都会被创建并存在。即使在错误场景下给它设置了errorMessage,关闭它时之前订阅的selectedPortfolio流仍会触发,进而导致异常弹出选择确认相关逻辑。
此外,原代码中用takeUntil(modalRef.content!.selectedPortfolio)管理API订阅的方式不合理,若错误场景下selectedPortfolio未发出值,会造成订阅泄漏。
解决方案
调整逻辑顺序:先调用API获取结果,根据返回值判断是展示错误提示还是正常的结果模态框,避免错误场景下创建不必要的结果模态框。
代码修改示例
export class SelectPortfolioComponent implements OnDestroy { private unsubscribe$ = new Subject<void>(); search = new SelectPortfolioModel(); account: number; constructor( private service: SelectPortfolioService, private modalService: BsModalService, private router: Router ) {} ngOnDestroy(): void { this.unsubscribe$.next(); this.unsubscribe$.complete(); } submit(): void { // 先发起API请求,根据返回结果决定后续操作 this.service.getPortfolios(this.search) .pipe(takeUntil(this.unsubscribe$)) .subscribe((res) => { // 判断是否为无结果/错误场景 const noResults = res.RETURNLIST.find( (item) => item.CODE === ApiResponseCodeEnum.Sch00 ); if (noResults) { // 错误场景:打开专门的错误提示模态框 this.modalService.show(ErrorModalComponent, { class: "modal-dialog-centered", initialState: { errorMessage: noResults.TEXTE } }); return; } // 正常场景:打开结果模态框并处理选择逻辑 const modalRef = this.modalService.show( SelectPortfolioResultModalComponent, { ...NOT_CLOSABLE_MODAL_OPTIONS, class: "modal-dialog-centered modal-lg", ariaLabelledBy: "modal-result-title", initialState: { isLoading: false, portfolios: res.PTF } } ); modalRef.content!.selectedPortfolio.pipe(takeUntil(this.unsubscribe$)) .subscribe((val: SelectPortfolio | undefined) => { if (val) { this.service.selectPortfolio(val) .pipe(takeUntil(this.unsubscribe$)) .subscribe(() => { this.router.navigate(["/portfolio/valorisation"]); }); } modalRef?.hide(); }); }); } }
修改说明
- 调整逻辑顺序:先执行API请求,根据返回结果分支处理,避免错误场景下创建结果模态框;
- 错误场景单独处理:使用专门的错误模态框展示提示,彻底隔离错误流程与正常流程;
- 优化订阅管理:统一使用组件的
unsubscribe$管理所有订阅,避免泄漏; - 提前传入数据:正常场景下直接将已获取的
portfolios传入模态框初始化参数,无需再设置isLoading状态。
内容的提问来源于stack exchange,提问作者MarinaLaGrande
相关产品推荐
相关产品推荐

