【问题标题】:"No value accessor for form control with path" despite using formBuilder.control尽管使用了 formBuilder.control,但“没有带路径的表单控件的值访问器”
【发布时间】:2020-11-13 09:58:33
【问题描述】:

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

dynamicValue 是设置的当前值,在拨动开关的情况下,它将是真或假。

下面的代码创建了一个 FormGroup,其中包含一个 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" declared 的父组件的 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).

【问题讨论】:

    标签: angular angular-reactive-forms


    【解决方案1】:

    Jake,Futhermore Chellppan 说,你不能单独在 App-boolean-setting 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的值

    【讨论】:

      【解决方案2】:

      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>
      

      【讨论】:

      • 如果这个答案不存在,我会花很多时间。
      猜你喜欢
      • 2017-04-25
      • 2021-02-28
      • 2018-01-21
      • 2020-12-16
      • 1970-01-01
      • 1970-01-01
      • 2020-07-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多