在单元测试中遇到Angular嵌套形式错误,错误是什么?

时间:2019-09-06 02:36:02

标签: angular angular-reactive-forms reactive-forms

所以在单元测试嵌套角度形式时出现以下错误:

 No value accessor for form control with path: 'address -> address1'

      at _throwError (../packages/forms/src/directives/shared.ts:140:9)
      at setUpControl (../packages/forms/src/directives/shared.ts:37:27)
      at FormGroupDirective.addControl (../packages/forms/src/directives/reactive_directives/form_group_directive.ts:132:5)
      at FormControlName._setUpControl (../packages/forms/src/directives/reactive_directives/form_control_name.ts:278:66)
      at FormControlName.ngOnChanges (../packages/forms/src/directives/reactive_directives/form_control_name.ts:207:28)

表单定义如下

ngOnInit() {
  this.form = this.fb.group({
    address: this.fb.group({
      address1: '',
      address2: '',
      ...
    })
  })
}

模板:

<form formGroup="form">
        <form formGroupName="address">
          <custom-text-input formGroupName="adress1" label="Address 1">
          </custom-text-input>
          <custom-text-input formGroupName="adress2" label="Address 1">
          </custom-text-input>
          <custom-text-input formGroupName="phone" label="Phone">
          </custom-text-input>
          <custom-text-input formGroupName="zipCode" label="Zip Code">
          </custom-text-input >
          <custom-text-input formGroupName="state" label="State">
          </custom-text-input >
        </form>
      </form>

1 个答案:

答案 0 :(得分:1)

我认为您在嵌套表单控件时错过了另外的this.fb.group({})

this.form = this.fb.group({
   address: this.fb.group({
      address1: [''],
      address2: ['']
   })
})

请阅读Reactive Forms - Generating form controls 上的官方文档


此外,formControlName仅与<input><select><textarea>一起使用。如果您在其他任何元素上使用过formControlName,请仔细检查您的模板文件。

如果您希望将formControlName与另一个表单控件一起使用,则必须使用ControlValueAccessor类来创建自定义表单控件。请参阅此alligator.io在creating custom form controls上的文章。


编辑

除了formGroupName输入绑定之外,还有formControlName输入绑定用于在FormGroup内部声明的控件。

摘自Angular的官方文档Associating the FormGroup model and view

  

由FormControlName指令提供的formControlName输入将每个单独的输入绑定到FormGroup中定义的表单控件。表单控件与它们各自的元素进行通信。他们还将变更信息传达给表单组实例,从而为模型值提供了真实来源。

  this.form = this.fb.group({
    address: this.fb.group({
      address1: '',
      address2: '',
      ...
    })
  })

//is equal to

   this.form = new FormGroup({
      address: new FormGroup({
          address1: new FormControl(''),
          address2: new FormControl('') 
      })
   })

如您所见,address1和address2不是表单组的新实例。我认为,如果您使用formControlName而不是formGroupName,则您的代码应该可以工作。

<form [formGroup]="form">
    <form formGroupName="address">
        <custom-text-input formControlName="adress1" label="Address 1">
        </custom-text-input>
        <custom-text-input formControlName="adress2" label="Address 1">
        </custom-text-input>
        <custom-text-input formControlName="phone" label="Phone">
        </custom-text-input>
        <custom-text-input formControlName="zipCode" label="Zip Code">
        </custom-text-input>
        <custom-text-input formControlName="state" label="State">
        </custom-text-input>
    </form>
</form>