如何将复选框动态添加到 angular 表单 (Angular 4)

How to add checkbox dynamically to angular forms (Angular 4)

我正在研究 angular 4 表单和 Angular 表单,如何在构建表单后动态地将输入(复选框)添加到 formArray。

ts:

signes_p = [
  { id: 'x1', name: 'bus' },
  { id: 'x2', name: 'car' }
];

ngOnInit() {
  const controls = this.signes_p.map(c => new FormControl(false));
  this.form = this.fb.group({
    signes: new FormArray(controls),
  });
}

addSigne(){
  if(this.new_signe && this.new_signe.trim().length>0){

    this.signes_p.push({
      id: this.new_signe,
      name: this.new_signe.replace(/^\w/, c => c.toUpperCase())
    })
  const controls = this.signes_p.map(c => new FormControl(false));
  const control = <FormArray>this.form.controls['signes'];
  var x = this.fb.group(controls[controls.length-1])
  control.push(x);
  }
}

html

<form [formGroup]="form" (ngSubmit)="onSubmit()">
      <div class="form-group" >
        <label for="signes" class="col-2 col-form-label" >Signes</label>  
          <div class="custom-control custom-checkbox" formArrayName="signes" *ngFor="let signe of form.controls.signes.controls; let i = index">
            <input type="checkbox" class="custom-control-input" [formControlName]="i" id="{{i}}">
            <label class="custom-control-label" for="{{i}}"> {{signes_p[i].name}}</label>
          </div>

          <div class="row" style="margin-top:20px;">
              <input class="form-control col-2" type="text" placeholder="Ajouter un autre..." [(ngModel)] = "new_signe" [ngModelOptions]="{standalone: true}" > 
              <a class="btn btn-success btn-sm" style="color: white;margin-left: 10px;" (click)="addSigne()"><i class="fa fa-plus" aria-hidden="true"></i></a>
          </div>        
      </div>
    ...
  <button class="btn btn-primary" type="submit" [disabled]="!form.valid">Enregistrer</button>   
</form>

我也试过这个 medium_example,它在 html

中引起了这些问题

control.registerOnChange is not a function

Must supply a value for form control with name: 'validator'.

来源linkStackBlitz

有几件事,根据下面的代码应该会变得清楚...在您的 stackblitz 上,替换以下 2 个文件中的代码 - 检查 console.log 以获得解决方案也对你的错误。

将现有的 app.component.ts 替换为以下

import { Component } from '@angular/core';
import { FormBuilder, FormGroup, FormArray, FormControl } from '@angular/forms';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {

  form: FormGroup
  constructor(private fb: FormBuilder, ) { this.initiate(); }

  insertedID: string;
  insertedName: string;


  fields = this.fb.group({
    elementArray: this.fb.array([this.createElementData('1', 'car')])
  });

  initiate() {
    const newRow2 = this.createElementData('2', 'bus');
    this.elementArray.push(newRow2);
  }

  createNew() {
    const newRow = this.createElementData(this.insertedID, this.insertedName);
    this.elementArray.push(newRow);
  }

  get elementArray(): FormArray {
    return this.fields.get("elementArray") as FormArray;
  }

  createElementData(passedID, passedName): FormGroup {
    if (passedID == 0 || !passedID) {
      passedID = this.elementArray.length + 1;
    }
    return this.fb.group({
      id: [passedID],
      name: [passedName],
      statusVal: false
    });
  }

  showData() {
    if (this.fields.value.elementArray.length > 0) {
      console.log(this.fields.value.elementArray);
    }
  }

}

export class Element {
  id: string;
  name: string;
  statusVal: boolean;
}

用以下

替换现有的app.component.html

<form [formGroup]="fields" class="example-form" (submit)="showData()">
  Signes:
  <div class='' formArrayName='elementArray' *ngFor="let item of fields.get('elementArray').controls; let i = index">
    <div [formGroupName]="i">
      <!-- <input type="text" formControlName="id" placeholder="Enter ID">  ID: [{{item.value.id}}] -->
      <input type="checkbox" formControlName="statusVal" placeholder="Enter Name">
      <!-- <input type="text" formControlName="name" placeholder="Enter Name"> -->{{item.value.name}}

    </div>
  </div>
  <div class="buttonDiv">
    <button type="submit" mat-raised-button color="primary">Enregistrer</button>
    <br/><br/> form status: <mark>{{fields.status}}</mark>
  </div>
</form>

<hr/>
<!-- <input type='text' [(ngModel)]="insertedID" placeholder="ID du nouveau véhicule" /> -->
<input type='text' [(ngModel)]="insertedName" placeholder="Ajouter un autre" />
<button mat-raised-button color="primary" (click)="createNew()"> Ajouter un nouveau véhicule et checkbox </button>