未设置子组件中输入属性的角度异步管道

时间:2019-02-01 17:17:27

标签: javascript angular typescript rxjs ngrx

子组件似乎只有在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为一个完整的形式组(因此它应该触发变化检测),但“集合形式”不记录。第二个值是我实际上需要在模板中设置的值。

是否存在仅在可观察对象首次发出时设置子组件属性的原因?

1 个答案:

答案 0 :(得分:2)

我相信您的问题只会在您拥有ChangeDetectionStrategyOnPush时发生。您正在this.form$钩子中设置ngAfterViewInit,因为有getFormGroup方法,对吗?有解决此两种方法。

使用ChangeDetectorRef

轻松

容器组件:

constructor(readonly cd: ChangeDetectorRef) {}

ngAfterViewInit(): void {
   // ...

   this.form$ = this.createOrderStore.pipe(select(getFormGroup));
   this.cd.markForCheck();
}

另一种方法是使用Subject更新formGroup,并在使用{p>的类构造中已定义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$属性未定义。这是您登录子组件时未定义的,并且因为您是在form$钩子中设置ngAfterViewInit,所以更改检测器不会拾取它,除非您专门告诉它去检查