输入材料芯片-初始化表格数组

时间:2018-08-28 15:11:38

标签: javascript arrays angular forms formbuilder

我想使用输入数据来初始化输入的席筹码,但是当我有两张筹码时,它仅形成一种形式:

enter image description here

*。component.ts

@Component({
  selector: 'app-pps-dialog',
  templateUrl: './pps-dialog.component.html',
})

export class PPSDialogComponent  implements OnInit {

patientid: string;
ppsForm: FormGroup;
ppssToDisplay;


visible: boolean = true;
selectable: boolean = true;
removable: boolean = true;
addOnBlur: boolean = true;
// Enter, comma
separatorKeysCodes = [ENTER, COMMA];


constructor(
private route: ActivatedRoute, 
private ppssService:PPSsService,
private _changeDetectorRef: ChangeDetectorRef,
private location: Location,
private router: Router, 
public dialog: MatDialog, 
private formBuilder: FormBuilder,
public dialogRef: MatDialogRef<PPSDialogComponent>,
@Inject(MAT_DIALOG_DATA) public data: any) 

{ this.initForm(); }

ngOnInit(): void {
    this.ppssToDisplay = this.ppssService.getSinglePPS(this.key)
      .subscribe(res => {
        this.ppssToDisplay = res;
        this.ppsForm.controls['requirements'].setValue(Array(this.ppssToDisplay.effetsind));
            console.log(this.ppssToDisplay.effetsind)); 
      });


  add(event: MatChipInputEvent): void {
        let input = event.input;
        let value = event.value;
        // Add our requirement
        if ((value || '').trim()) {
            this.requirements = this.ppsForm.get('requirements') as FormArray;
            this.requirements.push(this.formBuilder.control(value.trim()));
        }
        // Reset the input value
        if (input) {
            input.value = '';
        }
    }

    remove(index: number): void {
        const requirements = this.ppsForm.get('requirements') as FormArray;

        if (index >= 0) {
            requirements.removeAt(index);
        }
    }

        initForm(): void {
            this.ppsForm = this.formBuilder.group({
               requirements: this.formBuilder.array(['']),
               // I don't know why, but I must init my form with empty chips if I want to receive data from service.
            });
        }

        get formData() {
          return <FormArray>this.ppsForm.get('requirements');
        }

* ppss.service

import { Injectable } from '@angular/core';
import { Patient } from '../models/patient.model';
import { PPS } from '../models/pps.model';
import { AngularFireDatabase, AngularFireList, AngularFireObject} from 'angularfire2/database';
import { Observable } from 'rxjs/Observable';
import {switchMap, map} from 'rxjs/operators';
import * as firebase from 'firebase';
import DataSnapshot = firebase.database.DataSnapshot;


@Injectable({
  providedIn: 'root'
})
export class PPSsService {
ppss: AngularFireList<any>;

constructor(private database: AngularFireDatabase) {this.ppss = database.list('ppss');}
getSinglePPS(key: string){
    return this.database.object('ppss/' + key).valueChanges();
   }

}
  

console.log( this.ppssToDisplay.effetsind ):

 (2) ["Troubles de la vessie", "Troubles de l'érection"]

我用过example of Angular Material

*。component.html

<mat-form-field style="width:50%" appearance="outline">
  <mat-label>Description du traitement</mat-label>
  <textarea matInput formControlName="description"></textarea>
</mat-form-field>

<mat-form-field style="width:50%" appearance="outline">
  <mat-label>Effets indésirables du traitement</mat-label>
  <mat-chip-list #chipList>
    <mat-chip *ngFor="let requirement of formData.controls; let i = index;" [selectable]="selectable"
              [removable]="removable" (removed)="remove(i)">
      {{requirement.value}}
      <mat-icon matChipRemove *ngIf="removable">cancel</mat-icon>
    </mat-chip>
    <input placeholder="Nouvel effet indésirable..."
           [matChipInputFor]="chipList"
           [matChipInputSeparatorKeyCodes]="separatorKeysCodes"
           [matChipInputAddOnBlur]="addOnBlur"
           (matChipInputTokenEnd)="add($event)"/>
  </mat-chip-list>
</mat-form-field>
  

错误错误:必须在索引:0处提供表单控件的值:

> core.js:1598 ERROR Error: Must supply a value for form control at index: 0.
        at forms.js:4304
        at forms.js:4274
        at Array.forEach (<anonymous>)
        at FormArray.push../node_modules/@angular/forms/fesm5/forms.js.FormArray._forEachChild (forms.js:4274)
        at FormArray.push../node_modules/@angular/forms/fesm5/forms.js.FormArray._checkAllValuesPresent (forms.js:4302)
        at FormArray.push../node_modules/@angular/forms/fesm5/forms.js.FormArray.setValu

如果我用:[“ Troubles de la vessie”,“ Troubles de l'érection”,...]来初始化表单,我也会遇到同样的问题

1 个答案:

答案 0 :(得分:8)

反应性FormArray的使用非常棘手。检查以下最小有效示例:

import {Component, OnInit} from '@angular/core';
import {COMMA, ENTER} from '@angular/cdk/keycodes';
import {FormArray, FormBuilder, FormGroup} from '@angular/forms';
import {MatChipInputEvent} from '@angular/material';

@Component({
  selector: 'app',
  template: `
    <mat-form-field [formGroup]="formData">
      <mat-label>Effets indésirables du traitement</mat-label>
      <mat-chip-list #chipList>
        <mat-chip *ngFor="let requirement of formData.get('requirements').value; let i = index;"
                  [selectable]="selectable"
                  [removable]="removable"
                  (removed)="remove(i)">
          {{requirement}}
          <mat-icon matChipRemove *ngIf="removable">cancel</mat-icon>
        </mat-chip>
        <input
          placeholder="Nouvel effet indésirable..."
          [matChipInputFor]="chipList"
          [matChipInputSeparatorKeyCodes]="separatorKeysCodes"
          [matChipInputAddOnBlur]="addOnBlur"
          (matChipInputTokenEnd)="add($event)"/>
      </mat-chip-list>
    </mat-form-field>
  `
})
export class AppComponent implements OnInit {

  formData: FormGroup;
  selectable = true;
  removable = true;
  addOnBlur = true;
  readonly separatorKeysCodes: number[] = [ENTER, COMMA];

  constructor(private formBuilder: FormBuilder) {}

  ngOnInit() {
    this.initForm();
    this.ppssToDisplay();
  }

  initForm(): void {
    this.formData = this.formBuilder.group({
      requirements: this.formBuilder.array([]),
    })
  }

  ppssToDisplay() {
    // Simulate your async call to ppssService
    setTimeout(() => {
      const control = <FormArray>this.formData.controls.requirements;
      ['Troubles de la vessie', 'Troubles de l\'érection'].map(x =>
        control.push(this.formBuilder.control(x))
      );
    }, 300)
  }

  add(e: MatChipInputEvent) {
    const input = e.input;
    const value = e.value;

    if ((value || '').trim()) {
      const control = <FormArray>this.formData.controls.requirements;
      control.push(this.formBuilder.control(value.trim()));
    }

    if (input) {
      input.value = '';
    }
  }

  remove(i: number) {
    let control = <FormArray>this.formData.controls.requirements;
    control.removeAt(i);
  }
}