尽管使用formBuilder.control,但“没有带路径的表单控件的值访问器”

时间:2020-07-23 15:52:11

标签: angular angular-reactive-forms

我正在尝试根据后端提供的一些设置信息以程序方式生成Angular表单。为此,发送请求以检索数据,然后我试图基于该数据构建反应形式。

dynamicValue是设置的当前值,如果是拨动开关,则为true或false。

下面的代码创建一个FormGroup,其中包含一个formArray,然后该formArray会将settingsData数组中的每个设置的值推送到新控件。

组件:

    this.form = this.formBuilder.group({
      settingsArray: this.formBuilder.array([])
    });

    this.settingsData.forEach((settings: ClientSetting) => {
      this.settingsArray.push(
        this.formBuilder.control(settings.dynamicValue)
      )
    });

然后在我的模板中这样做

<div [formGroup]="form">
        <div formArrayName="settingsArray">
          <div *ngFor="let settings of settingsArray.controls; let i = index">
                <app-boolean-setting [formControlName]="i" [settingData]="settingsData[i]"></app-boolean-setting>
          </div>
        </div>
</div>

应用布尔设置模板

<div class="cont">
    <span>{{settingData.description.label}}</span>
    <mat-slide-toggle formControlName="{{formControlName}}" checked="{{settingData.description}}"></mat-slide-toggle>
</div>

app-boolean-setting组件只有两个输入:

@Input() public settingData: ClientSetting;
@Input() public formControlName: string;

但是,当我运行代码时,出现两个错误:

Error: No value accessor for form control with path: 'settingsArray -> 0'

这是BooleanSetting模板中的错误,因为它似乎无法找到formGroup,即使它位于已声明[formGroup]="form" 的父组件的div中?

Error: formControlName must be used with a parent formGroup directive.  You'll want to add a formGroup
       directive and pass it an existing FormGroup instance (you can create one in your class).

2 个答案:

答案 0 :(得分:0)

formControlName名称已由angular使用,以创建formControlDirective的实例。因此,将您的Input属性更改为其他类似的名称。

app-boolean-setting.ts

@Input() public settingData: ClientSetting;
@Input() public customFormControlName: string;

component.ts

<div [formGroup]="form">
        <div formArrayName="settingsArray">
          <div *ngFor="let settings of settingsArray.controls; let i = index">
                <app-boolean-setting [customFormControlName]="i" [settingData]="settingsData[i]"></app-boolean-setting>
         </div>
        </div>
</div>

答案 1 :(得分:0)

Jake,Futhermore Chellppan说,您不能仅在App布尔设置formControlName="{{formControlName}}"中使用

一种易于解决的方法是,您的app-boolean-settings具有一个FormControl作为输入

  //in your app-boolean-settings
  control:FormControl
  @Input('control') set f(value:AbstractControl)
  {
    this.control=value as FormControl
  }

  <div class="cont">
     <span>{{settingData.description.label}}</span>
     <!--use directly [formControl]="control"-->
     <!-don't use checked to give value, the slide get the value of the control (*)->
     <mat-slide-toggle [formControl]="control">
      </mat-slide-toggle>
  </div>

您使用

<div [formGroup]="form">
    <div formArrayName="settingsArray">
      <div *ngFor="let settings of settingsArray.controls; let i = index">
            <!--see how you pass directly the "FormControl"-->
            <app-boolean-setting [control]="settings"
              [settingData]="settingsData[i]"></app-boolean-setting>
      </div>
    </div>
</div>

(*)关于删除checked="{{settingData.description}}",当您有一个输入,mat-input,mat-slide-toggle ...已经具有formControl时,它将获取formControl的值