【问题标题】:Angular Control View Accessor doesn't detect value changed after writeValue method is called调用 writeValue 方法后,Angular Control View Accessor 未检测到更改的值
【发布时间】:2019-12-17 15:18:40
【问题描述】:

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

假设我有一个地址对象,我想将它映射到 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, emitEvent: true }) 方法。但我无法解决这个问题。

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

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

【问题讨论】:

    标签: angular


    【解决方案1】:

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

    import {startWith} from 'rxjs/operators';
    
    
    registerOnChange(fn) {
      this.form.valueChanges.pipe(startWith(this.form.value)).subscribe(fn);
    }
    

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

    【讨论】:

    • 这是问题的确切解决方案。完美运行。谢谢安德鲁·艾伦!
    猜你喜欢
    • 2019-01-05
    • 2017-09-18
    • 2017-04-01
    • 2021-09-16
    • 2020-01-08
    • 2016-05-30
    • 2020-12-22
    • 2019-06-06
    • 1970-01-01
    相关资源
    最近更新 更多