You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 08:10:39