如何将Push替换为Splice?及Promise.all加载数据异常排查
二、Loading状态不显示、数据不渲染问题
1. 修复Promise.all的函数调用错误
你的ngOnInit里,Promise.all([this.getData1, this.getData2])传入的是函数引用,没有执行函数,导致Promise.all根本没在等待异步请求完成。必须改为调用函数(加()):
ngOnInit(): void { // 初始设为true,显示loading this.processing = true; Promise.all([this.getData1(), this.getData2()]).then(values => { console.log(values); // 加载完成后关闭loading,设为false this.processing = false; }).catch(reason => { console.log('error get data', reason); this.processing = false; }); }
2. 解决Angular变更检测失效问题
原生Promise的回调不在Angular的变更检测范围内,可能导致变量更新后页面不渲染。有两种解决方式:
方式一:改用RxJS的forkJoin(推荐,符合Angular生态)
把getData系列函数改成返回Observable,用forkJoin合并请求:
import { forkJoin, tap } from 'rxjs'; ngOnInit(): void { this.processing = true; forkJoin([this.getData1(), this.getData2()]).subscribe({ next: values => { console.log(values); this.processing = false; }, error: reason => { console.log('error get data', reason); this.processing = false; } }); } public getData1() { return this.createService.getServiceData1().pipe( tap((response: any) => { let customFieldOption: CustomFieldOption = new CustomFieldOption(); this.opcionServicio = response; this.opcionesServicio.splice(0, 0, this.opcionServicio); this.servicio.splice(0, 0, this.opcionServicio.ticket_field.title); customFieldOption.id = this.opcionServicio.ticket_field.id; customFieldOption.name = this.opcionServicio.ticket_field.title; this.customFieldOptions.splice(0, 0, customFieldOption); }) ); } // getData2按同样逻辑修改,返回Observable
方式二:手动触发变更检测
如果坚持用Promise,注入ChangeDetectorRef手动标记变更:
import { ChangeDetectorRef } from '@angular/core'; constructor(private cdr: ChangeDetectorRef) {} ngOnInit(): void { this.processing = true; Promise.all([this.getData1(), this.getData2()]).then(values => { console.log(values); this.processing = false; // 手动通知Angular更新视图 this.cdr.markForCheck(); }).catch(reason => { console.log('error get data', reason); this.processing = false; this.cdr.markForCheck(); }); }
3. 检查模板绑定逻辑
确保页面模板正确绑定processing变量,比如:
<!-- 显示loading --> <div *ngIf="processing">加载中...</div> <!-- 加载完成后显示数据 --> <div *ngIf="!processing"> <ul> <li *ngFor="let title of servicio">{{ title }}</li> </ul> </div>
内容的提问来源于stack exchange,提问作者ALAIN TORRES
相关产品推荐
相关产品推荐

