调用writeValue方法后,Angular Control View Accessor无法检测到更改的值

时间:2019-12-17 15:18:40

标签: angular

我将Angular Control值访问器接口用于项目中的可重用表单。而且我在构建父表单时遇到设置值的问题。

假设我有一个Address对象,我想将其映射到cva表单中,并且此对象具有比实际表单更多的字段。 因此,在父组件中,我构建了表单:

constructor(private formBuilder: FormBuilder) {
   const address = new Address({
      id: 1,
      city: 'Roma',
      streetAddress: 'via Roma',
      houseNumber: '12b',
      postalCode: 43213,
      addressType: 'abitazione',
      addInfo: 'primo piano'
   });
    this.addressForm = this.formBuilder.group({
      address: [address],
    });
  }


<form [formGroup]="addressForm" (ngSubmit)="submit()">
  <app-address-cva formControlName="address"></app-address-cva>
  <button>Sign Up</button>
</form>

在子组件中,我处理父组件传递的值:

 writeValue(value: Address) {
if (value) {
  this.value = value;
}
if (value === null) {
  this.form.reset();
}

}

 set value(value) {
this.cityControl.setValue(value.city);
this.streetAddressControl.setValue(value.streetAddress);
this.houseNumberControl.setValue(value.houseNumber);
this.postalCodeControl.setValue(value.postalCode);
this.onChange(value);
this.onTouched();

}

提交表单时,我没有得到子cva表单的值,而是得到了父级传递的地址对象。如果表单字段未被用户触摸,则属于这种情况。如果子窗体的任何输入被触摸,则子窗体将返回窗体控件的值,并且一切正常。

我尝试使用更改检测,在writeValue方法中以编程方式将cva表单文件标记为已触摸且脏了,我甚至尝试调用updateValueAndValidity({onlySelf:false,酋长:true})方法。但是我无法解决这个问题。

这里是stackblitz项目,用于显示确切的问题: [https://stackblitz.com/edit/angular-ggepd6?file=src%2Fapp%2Fapp.component.ts]

如果有人可以帮助我解决这个问题,我将不胜感激。

1 个答案:

答案 0 :(得分:0)

您可以执行以下操作来强制使用第一个值:

import {startWith} from 'rxjs/operators';


registerOnChange(fn) {
  this.form.valueChanges.pipe(startWith(this.form.value)).subscribe(fn);
}

当您尝试以这种方式处理表单时,变更检测有一种与您不利的习惯,尽管并非不可能。问题是更改检测从父级到子级(单向流)起作用,而不是相反。

相关问题