Angular 动态 formArray 找不到控件

Angular dynamic formArray can't find the controls

我在 FormArray 的帮助下构建动态表单时遇到问题,我正在尝试基于包含 Object 描述数据库行的数组构建表单。目标是向用户显示他选择的每一行及其当前值,让用户修改它们并将它们发回。

所以一切都需要模块化,因为我不知道他选择的行数,也不知道 table 的列数,而且我仍然需要能够检索新数据。

我设法做了一些应该有效的事情,但我仍然有错误:

Error : Cannot find control with name: 'XXXXX'

我觉得这可能是一个关于 lifeCycleHook 的故事,html 在 typescript 中设置控件之前以某种方式执行。

我首先创建了一个名为 modifyForm 的 formArray 和一个 formBuilder

 modifyForm: FormArray;

 constructor private fb: FormBuilder){}

然后在我的 ngOnInit 函数中我创建了一个循环,用正确的控件填充 modifyForm 并填充 HTML 将用于创建用户界面的 externalArray。

打字稿:

ngOnInit() {


    let internalObjects = {}

    for (let i = 0; i < this.selectedRows.length; i++) {
      const row = this.selectedRows[i];
      internalObjects = {}

      for (let y = 0; y < Object.keys(row).length; y++) {
        const key = Object.keys(row)[y];
        const value = Object.values(row)[y];

        if (key !== "#") {
          this.modifyForm.push(this.fb.control(i + key))
          internalObjects[key] = value;
        }
      }
      this.externalArray.push(internalObjects)
    }
  }
}

HTML :

<form [formGroup]="modifyForm">
        <div *ngFor="let object of externalArray; let item = index ">
                <div *ngFor="let value of object | keyvalue">
                    <mat-form-field>
                       <input matInput [formControlName]='item+value.key' [value]='value.value'>
                    </mat-form-field>
               </div>
         </div>
</form>

奇怪的是,在 ngOnInit 函数的末尾,我控制台记录了它似乎使用正确值创建的控件,但它仍然说找不到它们。

打字稿循环:

   for (const control of this.modifyForm.controls) {
      console.log(control.value)
    }

结果:

我知道需要消化的内容很多,我已尽力提供尽可能多的信息,希望阅读起来不会太难。我已经找了好几天了,但我仍然被困在这里。感谢任何可以提供帮助的人! :)

您没有正确绑定到表单数组。使用表单组和表单数组,您可以绑定到键。对于表单数组,这是索引。

this.modifyForm.push(this.fb.control(i + key))

这是在表单数组的下一个可用索引处添加值为 i + key 的表单控件。

在您的 HTML 中,您应该绑定到索引而不是值。您不需要手动设置来自表单绑定的 [value]

<input matInput [formControlName]='item' />

其中 item*ngFor

中定义的表单数组中的当前索引

绑定到复杂对象

如果您想创建一个包含多个表单控件的数组,您可以设置一个表单组数组,您的 HTML 指令将反映您的表单结构。

const formGroups: FormGroup[] = myArray.map(x => new FormGroup({
  prop1: new FormControl(x.prop1),
  prop2: new FormControl(x.prop2)
}));
this.form = new FormArray(formGroups);
<form [formGroup]="form">
  <div *ngFor="let item of myArray; let i = index"
      [formGroupName]="i"> <!-- <<< bind to the ith form array entry -->
    <input formControlName="prop1" />
    <input formControlName="prop2" />
  </div>
</form>

绑定到未知属性

如果您不知道您的对象属性是什么,您可以从您的对象键创建您的表单。

this.form = new FormArray(this.selectedRows.map(row => {
  const formGroup = new FormGroup({});
  Object.keys(row).forEach(key => { // <-- use Object.keys to iterate the object
    formGroup.addControl(key, new FormControl(row[key]));
  });
  return formGroup;
}));

并从对象键

生成你的HTML
<form [formGroup]="form">
  <div *ngFor="let row of selectedRows;let i = index">                
    <div [formGroupName]="i">
      <!-- use the keyvalue pipe to iterate the key/value pairs of the object -->
      <span *ngFor="let keyvalue of row | keyvalue">
        <input [formControlName]="keyvalue.key" />
      </span>
    </div>
  </div>
</form>

演示:https://stackblitz.com/edit/angular-v1jd6x