如何在不声明的情况下将 FormArray 添加到 FormGroup 中,并以编程方式添加

问题描述 投票:0回答:1

我试图学习为表单创建通用模板,在传递 json 时,将定义 呈现的表格的结构。

如果不提前声明,我无法以编程方式将控件和表单数组添加到 fromGroup

https://stackblitz.com/edit/stackblitz-starters-ksvegt?file=src%2Fmain.ts

这是代码,请帮我解决这个问题,这是正确的方法吗

angular angular-reactive-forms
1个回答
0
投票

不要使用 setControl 否则 addControl

  createForm(jsonData: JsonForm) {
    this.form1.addControl('header', new FormControl(jsonData.header));
    const controlArray = this.fb.array([]);
    for (let control of jsonData.controls || []) {
      controlArray.push(this.fb.control(control.value));
    }
    this.form1.addControl('controls', controlArray);
  }

总是有一个 fromArray 使用 getter 来“到达”它并迭代它

  get controls()
  {
    return this.form1.get('controls') as any as FormArray
  }

你使用

  <form [formGroup]="form1">
    <div
      formArrayName="controls"
      *ngFor="let control of controls.controls; let i = index"
    >
      <input  [formControlName]="i" />
    </div>
  </form>

你的分叉堆栈闪电战

好吧,这解决了你的代码,但我觉得创建 formGroup 的方法实际上是创建一个 formGroup,而不是一个 formArray

这样你的formGroup的值就有了你的json数据的结构

为此,我向您的 JsonFormControls 界面添加一个新属性,

name
,它是属性的名称

  createForm(jsonData: JsonForm) {

    //to iterate over an array use forEach instead a for
    (jsonData.controls || []).forEach((control:JsonFormControls,index:number)=>{
      this.form1.addControl(control.name ||'ctrl'+index,
                            new FormControl(control.value))
    })
  }

那么,现在“如何迭代”?

迭代 jsonData.controls 不是一个好主意,否则你可以使用 keyvaluePipe

迭代 form.controls
<ng-template #DEFAULT_FORM_TITILE let-form="form1">
  <h2>{{ jsonData.header }}</h2>
  <form [formGroup]="form1">

   <!-see you iterate over form1.controls|keyvalue
      you use let i=index, to get the value of the jsonData.controls[i]
      -->
    <div *ngFor="let control of form1.controls|keyvalue;let i=index">

     <!--sorry the "!", it's to avoid errors of "object can be undefined"-->
     <label>{{jsonData!.controls![i].label}}

      <input [type]="jsonData!.controls![i]?.type || null" 
             [formControlName]="jsonData!.controls![i]?.name || null" />
      </label>
    </div>
  </form>

  <!--just for check-->
  <pre>
  {{form1.value|json}}
  </pre>
</ng-template>

A 新的堆栈闪电战

© www.soinside.com 2019 - 2024. All rights reserved.