Angular 8嵌套FormBuilder无法找到控件

时间:2019-12-19 23:14:27

标签: angular angular-reactive-forms formbuilder

我试图遍历Angular 8中FormBuilder中的值 路径是FormGroup-> FormArray-> FormGroup-> FormArray 但是我得到了这个错误: 找不到具有以下路径的控件:“条件-> 2->值-> 0-> [对象对象]” 我尝试了很多组合,但没有人起作用

在我的组件中:

conditionsForm: FormGroup;
  conditionForm: FormArray;
  conditionValuesForm: FormArray;

  ngOnInit() {
    this.conditionsForm = this.formBuilder.group({
      conditions: this.formBuilder.array([this.createConditionForm()])
    });
  }

  createConditionForm(): FormGroup {
    return this.formBuilder.group({
      type: "",
      operator: "",
      values: this.formBuilder.array([this.createConditionValuesForm()])
    });
  }

  createConditionValuesForm(): FormGroup {
    return this.formBuilder.group({
      value: ""
    });
  }

  addConditionForm(): void {
    this.conditionForm = this.conditionsForm.get("conditions") as FormArray;
    this.conditionForm.push(this.createConditionForm());
  }

  addConditionValuesForm(): void {
    this.conditionValuesForm = this.conditionForm.get("values") as FormArray;
    this.conditionValuesForm.push(this.createConditionValuesForm());
  }

在我的模板中:

<form [formGroup]="conditionsForm" class="row container-condition">
    <div formArrayName="conditions" *ngFor="let condition of conditionsForm.get('conditions').controls; let i_condition = index">
        <div class="row row-condition" [formGroupName]="i_condition">
            <!-- INPUT VALUE -->
            <div [formGroup]='condition'></div>
            <div formArrayName="values" *ngFor="let value of condition.get('values').controls; let i_value = index">
                <div [formGroupName]="i_value">
                    <mat-form-field class="example-full-width">
                        <input matInput placeholder="Value" value="" [formControlName]="value.value">
                    </mat-form-field>
                </div>
            </div>
        </div>
    </div>
    <button (click)="addConditionForm()">Add condition</button>
    <button type="button" (click)="printMyForm()">Print to console</button>
</form>

3 个答案:

答案 0 :(得分:1)

您的代码中似乎还存在其他与此无关的问题,即您没有将表单正确地视为数组数组,但是此特定错误的解决方法在这里;

<input matInput placeholder="Value" formControlName="value">

您最终的formControlName就是价值。

答案 1 :(得分:1)

轻微更改为html:

<form [formGroup]="conditionsForm">
    <div
     formArrayName="conditions"
     *ngFor="let condition of conditionsForm.get('conditions').controls; let i_condition = index">
        <div [formGroupName]="i_condition"> <!-- correctly binding dynamic index variable -->
            <!-- also note this: 'condition' is not a valid group name within the group you created for the 'conditions' array. --> 
            <!-- <div [formGroup]='condition'></div> --> 

          <input type="text" formControlName="type" placeholder="type"> <!-- hardcoded 'type' control name, as it is steady with all groups within 'condition' -->
          <input type="text" formControlName="operator" placeholder="operator">
            <div
             formArrayName="values"
             *ngFor="let value of condition.get('values').controls; let i_value = index">
                <div [formGroupName]="i_value"> <!-- correctly binding dynamic index -->
 <!-- instead of [formControlName]="value.value", which would approach to your ts file and look for a control in an object like this: value = {value: new FormControl()...} -->
                  <input placeholder="Value" value="" formControlName="value">
                </div>
            </div>
        </div>
    </div>
</form>

主要问题是属性绑定与文字绑定的并发混淆

请注意,formArray的直接子项被命名为0、1、2、3 ...,而组只有在您明确命名时才具有明确的名称,例如

this.myForm = this.formBuilder.group({
  myInput: [null],
  myGroup: this.formBuilder.group({...}),
  myArray: this.formBuilder.array([])
})

和html

<!-- property binding -->
<form [formGroup]="myForm"/>
   <!-- literal binding because parent is declared and known (myForm) -->
   <input formControlName="myInput"/>
   <!-- literal binding because parent is declared and known (myForm) -->
   <div formGroupName="myGroup">
   <!-- literal binding because parent is declared and known (myGroup) -->
      <input formControlName="nestedInput"/>
   </div>
   <!-- literal binding because parent is declared and known (myForm) -->
   <div formArrayName="myArray" *ngFor="let control of myForm.get('myArray').controls; let i_control = index">
   <!-- property binding because items in array are accessed by index, and not by name, and is generated on the fly, nowhere declared in your code (and shouldn't be) -->
      <input [formControlName]="i_control"/>
      <!-- or -->
      <div [formGroupName]="i_control">
        <!-- literal binding because parent is known by name (i_control) -->
        <input formControlName="myInputInOneOfTheGroupsOfMyArray"/>
      </div>
   </div>
</form>

stackblitz

答案 2 :(得分:0)

Object.keys(this.form.controls).forEach(key => {
  this.form.controls[key].CallAFunction(); // DO what you would like to do.
});

在这里查看详细信息。