看起来子组件仅在 Observable 第一次发出时才被设置。
容器组件(添加映射运算符用于调试):
this.form$ = this.createOrderStore.pipe(select(getFormGroup)).pipe(
tap((val) => {
console.log('observable emitted');
console.log(val);
return val;
})
);
子组件:
private _form: FormGroup;
@Input()
set form(val) {
console.log('set form');
if (val) {
this._form = val;
}
}
get form() {
return this._form;
}
容器模板:
<app-order-form [form]="form$ | async"></app-order-form>
第一次发出可观察值时,控制台显示“已发出可观察值”,val 未定义,然后显示“设置形式”。但是,由于第一个值未定义,因此我们尚未在模板中设置它。
第二次可观察值发出时,控制台记录“可观察值发出”,val 是一个完整的表单组(因此它应该触发更改检测),但不会记录“设置表单”。第二个值是我实际需要在模板中设置的值。
仅在可观察对象第一次发出时才设置子组件属性是否有原因?
最佳答案
我相信只有当您将 ChangeDetectionStrategy
更改为 OnPush
时,才会出现您的问题。由于 getFormGroup
方法,您可能在 ngAfterViewInit
Hook 中设置 this.form$
,对吗?有两种方法可以解决这个问题。
简单的方法,使用ChangeDetectorRef
容器组件:
constructor(readonly cd: ChangeDetectorRef) {}
ngAfterViewInit(): void {
// ...
this.form$ = this.createOrderStore.pipe(select(getFormGroup));
this.cd.markForCheck();
}
另一种方法是使用 Subject
来更新 formGroup,并使用 forms$
在类构造中定义
formGroup$ = new ReplaySubject<FormGroup>(1);
readonly form$ = this.formGroup$.pipe(
mergeMap((formGroup) => this.createOrderStore.pipe(
select(formGroup)
))
);
ngAfterViewInit(): void {
// ...
this.formGroup$.next(getFormGroup);
}
为了澄清目前代码中发生的情况,容器组件上的 form$
属性未定义。这是您在子组件中登录的未定义,并且因为您在 ngAfterViewInit
Hook 内设置 form$
,所以它不会被更改检测器拾取,除非你特意告诉它去检查
关于javascript - 未设置子组件中输入属性的 Angular 异步管道,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54484186/