Angular 8 嵌套的 FormBuilder 找不到控件

Angular 8 Nested FormBuilder Can't find control

我试图在 Angular 8 中迭代 FormBuilder 中的值 路径是FormGroup -> FormArray -> FormGroup -> FormArray 但是我得到了这个错误: 找不到路径为以下的控件:'conditions -> 2 -> values -> 0 -> [object Object]' 我尝试了很多组合,但没有一个有效

在我的组件中:

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>
Object.keys(this.form.controls).forEach(key => {
  this.form.controls[key].CallAFunction(); // DO what you would like to do.
});

在此处查看 details.It 过去已回答。

您的代码中似乎还有一些与此无关的其他问题,您没有将表单正确地视为数组的数组,但此特定错误的修复已在此处;

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

你的最终 formControlName 只是价值。

对 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: