简体   繁体   English

Angular 具有来自数组的动态字段的反应式表单

[英]Angular Reactive Form with dynamic fields from array

I am using Angular 9, and am trying to implement a component that uses reactive forms .我正在使用 Angular 9,并且正在尝试实现一个使用反应式 forms的组件。

I have the following:我有以下内容:

approval-edit.component.ts批准-edit.component.ts

  public nominationAllOf: NominationAllOf[];
  public approvalEditForm: FormGroup;

  ngOnInit(): void {
    this.approvalEditForm = new FormGroup({
      userName00: new FormControl(),
      userName01: new FormControl(),
      userName02: new FormControl(),
      userName10: new FormControl(),
      userName11: new FormControl(),
      userName12: new FormControl()
   })
  }

This works, however, you can see that the form group values need to be dynamic according to the values in an array ( nominationAllOf ).这可行,但是,您可以看到表单组值需要根据数组中的值( nominationAllOf )是动态的。

nominationAllOf is a 2 dimensional array. nominationAllOf是一个二维数组。

ie IE

export interface NominationAllOf {
    nominations: NominationAnyOf[];
}

and

export interface NominationAnyOf {
    name: string;
}

Question问题

Is it possible to populate the FormGroup dynamically?是否可以动态填充FormGroup

eg (this does not work)例如(这不起作用)

    this.approvalEditForm = new FormGroup({
      for (i = 0; i < nominationAllOf.length; i++) {
           for (j = 0; j < nominationAllOf[i].length; j++) {
               'userName'+i+''+j: new FormControl(nominationAllOf[i].nominationAnyOf[j].name)
           }
      }
      
   })
  }

The following works (ie addControl ):以下作品(即addControl ):

  private loadForm(): void {
    for (let i = 0; i < this.nominationAllOf.length; i++) {
      let nominationAnyOf: NominationAnyOf[] = this.nominationAllOf[i].nominations;
      for (let j = 0; j < nominationAnyOf.length; j++) {
          let name = nominationAnyOf[j].evaluatorInfo.personalInfo.name.firstName;
          this.approvalEditForm.addControl('userName'+i+''+j, new FormControl(name));
        }
      }
  }

There is a way to make this work with FormArray.有一种方法可以使用 FormArray。 You have it documented here: https://netbasal.com/angular-reactive-forms-the-ultimate-guide-to-formarray-3adbe6b0b61a你有它记录在这里: https://netbasal.com/angular-reactive-forms-the-ultimate-guide-to-formarray-3adbe6b0b61a

For your example it would work like this:对于您的示例,它将像这样工作:

this.approvalEditForm = new FormGroup({
  userNames: new FormArray([
    new FormControl(),
    new FormControl(),
    new FormControl(),
    new FormControl(),
  ]),
});

Since you have array of elements just populate them with map() method initialy, and when you are rendering them you will use ngFor and you will display them in that order.由于您有元素数组,只需使用map()方法初始填充它们,当您渲染它们时,您将使用ngFor并按该顺序显示它们。 If you want to add dynamically just push one of them from that FormArray like you would with regular array, or if you want to remove one you can use removeAt(indexNumber) method from FromArray.如果您想动态添加,只需像使用常规数组一样从该 FormArray 中推送其中一个,或者如果您想删除一个,您可以使用 FromArray 中的removeAt(indexNumber)方法。 You also have insert and clear methods for adding or clearing all elements from FromArray您还可以使用insertclear方法从 FromArray 添加或清除所有元素

Use Bracket notation to create dynamic key.使用括号表示法创建动态密钥。

  this.approvalEditForm = new FormGroup({
      for (i = 0; i < nominationAllOf.length; i++) {
           for (j = 0; j < nominationAllOf[i].length; j++) {
               ['userName'+i+''+j]: new FormControl(nominationAllOf[i].nominationAnyOf[j].name)
           }
      }
      
   })
  }

How about the following:以下情况如何:

constructor(private fb: FormBuilder) { }

ngOnInit(): void {
  this.approvalEditForm = this.fb.group(
    this.nominationAllOf
      .map((x, xi) => x.nominations.map(({ name }, yi) => ({ [`userName${xi}${yi}`]: [name] })))
      .reduce((x, y) => ({ ...x, ...y.reduce((a, b) => ({ ...a, ...b }), {}) }), {}) // double flattening 
  )
}

Alternatively using Flat或者使用Flat

this.approvalEditForm = new FormGroup(
  this.nominationAllOf
    .map((x, xi) => x.nominations.map(({ name }, yi) => ({ [`userName${xi}${yi}`]: new FormControl(name) })))
    .flat()
    .reduce((x, y) => ({ ...x, ...y }), {})
)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM