Angular 14父组件异步获取数据后向子组件传值失败如何解决
问题根源
子组件初始化执行ngOnInit的时机,早于父组件HttpClient异步请求返回数据的时机。子组件初始化时@Input()绑定的data还是默认空数组,此时给rateData赋值只会拿到空值;后续父组件异步请求完成更新allData时,子组件不会自动重新执行ngOnInit里的赋值逻辑,导致拿不到最新数据。
可行解决方案
以下三种方案按需选择即可:
方案1:控制子组件渲染时机(最简单)
父组件模板中通过
*ngIf判断数据是否加载完成,只有接口返回数据后再渲染子组件,这样子组件初始化时就能直接拿到完整的输入值。
父组件模板修改示例:<!-- app.component.html --> <app-auto *ngIf="allData.length" [data]="allData"></app-auto>该方案不需要修改子组件现有逻辑,适合子组件不需要在数据加载前展示的场景。
方案2:通过ngOnChanges监听输入属性变化
子组件实现
OnChanges生命周期,只要父组件传入的data值发生变化,就自动同步更新本地的rateData,不需要控制子组件渲染时机。
子组件代码修改示例:// auto.component.ts import { Component, Input, OnInit, OnChanges, SimpleChanges } from '@angular/core'; @Component({ selector: 'app-auto', templateUrl: './auto.component.html' }) export class AutoComponent implements OnInit, OnChanges { @Input() data: Array<string> = []; public rateData: Array<string> = []; constructor() {} ngOnInit(): void { this.rateData = [...this.data]; } ngOnChanges(changes: SimpleChanges): void { // 校验data输入项的变化,存在有效值时同步给rateData if (changes['data']?.currentValue?.length) { this.rateData = [...changes['data'].currentValue]; } } }方案3:用setter拦截输入属性更新
给
@Input()属性设置set拦截器,只要父组件传入新值,就自动触发更新逻辑,效果和ngOnChanges类似,写法更轻量。
子组件代码修改示例:// auto.component.ts import { Component, Input, OnInit } from '@angular/core'; @Component({ selector: 'app-auto', templateUrl: './auto.component.html' }) export class AutoComponent implements OnInit { private _data: Array<string> = []; @Input() set data(value: Array<string>) { this._data = value; // 输入值更新时同步给rateData this.rateData = [...value]; } get data(): Array<string> { return this._data; } public rateData: Array<string> = []; constructor() {} ngOnInit(): void { this.rateData = [...this.data]; } }
注意:数组赋值时建议用展开运算符
[...arr]做浅拷贝,避免子组件修改本地变量时意外篡改父组件的原数组数据,引发非预期的联动问题。
内容的提问来源于stack exchange,提问作者EMahan K
相关产品推荐
相关产品推荐

