Angular中如何将异步数据传递给子组件?
Angular子组件无法获取父组件传递的Booking数据问题
原实现逻辑
父组件发起HTTP请求并订阅获取数据:
this.bookingService.getBooking().subscribe((r) => { this.booking = r['result']; });
通过*ngIf控制子组件渲染,传递booking变量:
<child *ngIf="booking" [booking]="booking"></child>
子组件接收@Input并通过ngOnChanges监听变化,期望加载后立即使用数据:
@Input() booking: Booking; // ... ngOnChanges(changes: SimpleChanges) { if (changes['booking']) { this.createForm(this.booking.reference); } }
原预期父组件请求完成前booking会以undefined传递,但实际逻辑未生效。
补充场景:子组件为模态弹窗
点击父组件按钮触发弹窗显示时,子组件ngOnInit正常触发,但ngOnChanges未执行:
父组件.ts
openUpdateReservationPopup() { this.modalRef = this.modalService.show(UpdateReservationComponent, { class: 'modal-dialog-centered' }); }
父组件.html
<button class="btn btn-primary btn-sm" (click)="openUpdateReservationPopup()" *ngIf="showButton()"> <span class="booking-content-actions-label">Open popup</span> </button>
已尝试的无效方案
尝试将Observable直接传递给子组件(含/不含async管道),在子组件ngOnInit中订阅:
方案1:使用async管道传递
父组件.ts
this.bookingObservable$ = this.bookingService.getBooking(); this.bookingObservable$.subscribe((r) => { this.booking = r['result']; });
父组件.html
<child *ngIf="booking" [bookingObservable$]="bookingObservable$ | async"></child>
方案2:直接传递Observable
父组件.html
<child *ngIf="booking" [bookingObservable]="bookingObservable$"></child>
子组件.ts
@Input() bookingObservable$: any; ngOnInit() { this.bookingObservable$.subscribe((val) => { console.log(val); this.createReferenceNumberForm(val.reference); }); }
解决方案
核心问题:动态创建模态组件的传参方式
通过modalService.show()动态创建组件时,模板绑定的@Input不会生效,需通过initialState配置传递参数:
修改父组件代码
openUpdateReservationPopup() { // 若booking已加载,直接打开弹窗并传参 if (this.booking) { this.modalRef = this.modalService.show(UpdateReservationComponent, { class: 'modal-dialog-centered', initialState: { booking: this.booking } }); } else { // 若booking未加载,先请求数据再打开弹窗 this.bookingService.getBooking().subscribe((r) => { this.booking = r['result']; this.modalRef = this.modalService.show(UpdateReservationComponent, { class: 'modal-dialog-centered', initialState: { booking: this.booking } }); }); } }
子组件调整逻辑
@Input() booking: Booking; ngOnInit() { // 弹窗打开时已传入booking,直接在ngOnInit调用方法即可 this.createForm(this.booking.reference); } // 如需后续监听booking变化,保留ngOnChanges ngOnChanges(changes: SimpleChanges) { if (changes['booking']?.currentValue) { this.createForm(changes['booking'].currentValue.reference); } }
替代方案:子组件直接请求数据
若弹窗依赖的booking数据无需在父组件缓存,可直接在子组件发起请求:
// 子组件.ts ngOnInit() { this.bookingService.getBooking().subscribe((r) => { this.booking = r['result']; this.createForm(this.booking.reference); }); }
优化:避免重复请求
若父组件已订阅过Observable,用shareReplay复用请求结果:
// 父组件.ts import { shareReplay } from 'rxjs/operators'; this.bookingObservable$ = this.bookingService.getBooking().pipe(shareReplay(1));
内容的提问来源于stack exchange,提问作者programmer24
相关产品推荐
相关产品推荐

