1

I was trying to accomplish dynamic duplication using the FormArray but I just couldn't do it. Please check the form on JSFiddle.

component.html

<div class="form-group">
  <div formArrayName="nqCoordinators">
    <button class="col-md-offset-1 col-md-1 btn btn-default" type="button">
       Add Coordinator
    </button>
    <div class="form-group" [ngClass]="{'has-error': (agencyForm.get('nqCoordinators').touched || agencyForm.get('nqCoordinators').dirty) && !agencyForm.get('nqCoordinators').valid}"
         *ngFor="let nqCoordinator of nqCoordinators.controls; let i=index">
      <label class="col-md-2 control-label" [attr.for]="i">Coordinator</label>
      <div class="col-md-8">
        <input class="form-control" id="i" type="text" placeholder="NQ Coordinator" formControlName="i" />
      </div>               
    </div>
  </div>
</div>

component.ts

import {
  Component,
  OnInit
}
from '@angular/core';
import {
  FormGroup,
  FormControl,
  FormBuilder,
  Validators,
  FormArray
}
from '@angular/forms';
import {
  ActivatedRoute,
  Router
}
from '@angular/router';
import {
  Subscription
}
from 'rxjs/Subscription';


@Component({
  templateUrl: './newq.component.html'
})
export class CreateNewQComponent implements OnInit {
  pageTitle: string;

  agencyForm: FormGroup;


  private sub: Subscription;
  get nqCoordinators(): FormArray {
     return <FormArray>this.agencyForm.get('nqCoordinators');
  }

  constructor(private route: ActivatedRoute, private fb: FormBuilder, private router: Router) {}

  //myOptions: IMultiSelectOption[] = [
  //    { id: 1, name: 'Option 1' },
  //    { id: 2, name: 'Option 2' },
  //];

  ngOnInit(): void {
      this.agencyForm = this.fb.group({
        nqCoordinators: this.fb.array([]),
        //qAdvisors: '',
        nq1: '',
        nq2: '',
        nq3: '',
        nq4: '',
        nqCoordinators: this.fb.array([]),
        nqStartDate: ''        
      });

      this.agencyForm.controls['salesRep'].valueChanges
          .subscribe((selectedOptions) => {
              // changes
          });
      this.sub = this.route.params.subscribe(
        params => {
          let id = +params['id'];
          if (id === 0)
            this.pageTitle = 'Add Q';
          else
            this.pageTitle = 'Edit Q';
        }
      );

    }

  add() {
    console.log(this.newQForm);
    console.log('Saved: ' + JSON.stringify(this.newQForm));
  }

  addAgency() {
    console.log(this.newQForm);
    console.log('Saved: ' + JSON.stringify(this.newQForm));
  }

  backBtnClick() {
    this.router.navigate(['/newq']);
  }
}
4

1 回答 1

2

你有很多代码,所以这里有一个更简单的例子。

首先,您有一个嵌套<form>标签。这不仅行得通。相反,您应该[formGroup]在模板中只有一个 main(带有 form 标签)。模板中的其余部分应该是formControlName's. FormArrayName的和嵌套FormGroupName的。

所以这将是表单的构建,我们最初设置了一个协调器:

this.agencyForm = this.fb.group({
  agencyName: [''],
  nqCoordinators: this.fb.array([
    this.initNqCoordinators() // we'll use the same function for adding new
  ])
});

initNqCoordinators() {
  return this.fb.group({
    // here add all your form controls needed for your coordinator
    whatever_form_control: ['']
  })
}

在这里,当您单击模板添加新的协调器时,它看起来像这样:

addCoordinator() {
  // our formarray with coordinators
  const control = <FormArray>this.agencyForm.controls['nqCoordinators'];
  // we call function to push a new formgroup to the array
  control.push(this.initNqCoordinators())
}

然后您的模板将如下所示:

<form [formGroup]="agencyForm" (ngSubmit)="submit(agencyForm.value)">
  <label>Agency Name: </label>
  <input formControlName="agencyName"/><br><br>
  <button (click)="addCoordinator()">Add Coordinator</button><br>

  <div formArrayName="nqCoordinators">
     <div *ngFor="let child of agencyForm.controls.nqCoordinators.controls; let i = index" >
        <div formGroupName="{{i}}">
           <label>Whatever Coordinator formControl-name</label>
           <input formControlName="whatever_form_control" /><br><br>
        </div>
     </div>
  </div>
  <button type="submit">Submit</button>
</form>

带有上述内容的DEMO 。

于 2017-06-02T15:19:22.213 回答