Angular Reactive Forms with nested Form Arrays

生来就可爱ヽ(ⅴ<●) 提交于 2019-11-27 03:13:46

It's not very much different to have a nested formarray. Basically you just duplicate the code you have... with nested array :) So here's a sample:

myForm: FormGroup;

constructor(private fb: FormBuilder) {
  this.myForm = this.fb.group({
    // you can also set initial formgroup inside if you like
    companies: this.fb.array([])
  })
}

addNewCompany() {
  let control = <FormArray>this.myForm.controls.companies;
  control.push(
    this.fb.group({
      company: [''],
      // nested form array, you could also add a form group initially
      projects: this.fb.array([])
    })
  )
}

deleteCompany(index) {
  let control = <FormArray>this.myForm.controls.companies;
  control.removeAt(index)
}

So that is the add and delete for the outermost form array, so adding and removing formgroups to the nested form array is just duplicating the code. Where from the template we pass the current formgroup to which array you want to add (in this case) a new project/delete a project.

addNewProject(control) {
  control.push(
    this.fb.group({
      projectName: ['']
  }))
}

deleteProject(control, index) {
  control.removeAt(index)
}

And the template in the same manner, you iterate your outer formarray, and then inside that iterate your inner form array:

<form [formGroup]="myForm">
  <div formArrayName="companies">
    <div *ngFor="let comp of myForm.get('companies').controls; let i=index">
    <h3>COMPANY {{i+1}}: </h3>
    <div [formGroupName]="i">
      <input formControlName="company" />
      <button (click)="deleteCompany(i)">
         Delete Company
      </button>
      <div formArrayName="projects">
        <div *ngFor="let project of comp.get('projects').controls; let j=index">
          <h4>PROJECT {{j+1}}</h4>
          <div [formGroupName]="j">
            <input formControlName="projectName" />
            <button (click)="deleteProject(comp.controls.projects, j)">
              Delete Project
            </button>
          </div>
        </div>
        <button (click)="addNewProject(comp.controls.projects)">
          Add new Project
        </button>
      </div>
    </div>
  </div>
</div>

DEMO

EDIT:

To set values to your form once you have data, you can call the following methods that will iterate your data and set the values to your form. In this case data looks like:

data = {
  companies: [
    {
      company: "example comany",
      projects: [
        {
          projectName: "example project",
        }
      ]
    }
  ]
}

We call setCompanies to set values to our form:

setCompanies() {
  let control = <FormArray>this.myForm.controls.companies;
  this.data.companies.forEach(x => {
    control.push(this.fb.group({ 
      company: x.company, 
      projects: this.setProjects(x) }))
  })
}

setProjects(x) {
  let arr = new FormArray([])
  x.projects.forEach(y => {
    arr.push(this.fb.group({ 
      projectName: y.projectName 
    }))
  })
  return arr;
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!