javascript - Kan ikke legge til data i FormArray


Kan ikke oppdatere verdier til FormArray resultList.

Kan noen vennligst forklare meg hva jeg går glipp av?

TS-fil:

import { Component, OnInit } from '@angular/core';
import { Student } from '../student';
import { FormGroup, FormControl, Validators, FormArray } from '@angular/forms';

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

export class ContainerComponent implements OnInit {

  studList: Student[] = [];
  myform: FormGroup = new FormGroup({
    firstName: new FormControl('', [Validators.required, Validators.minLength(4)]),
    lastName: new FormControl(),
    gender: new FormControl('male'),
    dob: new FormControl(),
    qualification: new FormControl(),
    resultList: new FormArray([])
  });    

  onSave() {
    let stud: Student = new Student();
    stud.firstName = this.myform.get('firstName').value;
    stud.lastName = this.myform.get('lastName').value;
    stud.gender = this.myform.get('gender').value;
    stud.dob = this.myform.get('dob').value;
    stud.qualification = this.myform.get('qualification').value;
    this.studList.push(stud);
    this.myform.controls.resultList.patchValue(this.studList);
    console.log(JSON.stringify(this.studList));
  }

  ngOnInit() {
  }
}

Modell:

export class Student {
    public firstName: String;
    public lastName: string;
    public gender: string;
    public dob: string;
    public qualification: string;
}

HTML:

    <div class="container">
        <h3>Striped Rows</h3>
        <table class="table table-striped" formArrayName="resultList">
            <thead>
                <tr>
                    <th>Firstname</th>
                </tr>
            </thead>
            <tbody>
                <tr *ngFor="let item of myform.controls.resultList.controls; let i = index" [formGroupName]="i">
                    <td><p formControlName="firstName"></p></td>
                </tr>
            </tbody>
        </table>
    </div>

this.studList JSON:

[  
   {  
      "firstName":"santosh",
      "lastName":"jadi",
      "gender":"male",
      "dob":"2018-03-31T18:30:00.000Z",
      "qualification":"BE"
   },
   {  
      "firstName":"santosh",
      "lastName":"jadi",
      "gender":"male",
      "dob":"2018-03-31T18:30:00.000Z",
      "qualification":"BE"
   }
]

Svar #1

Ut fra spørsmålet ditt vil du legge til en ny Student i resultList. Først må du vite at FormArray er et array av AbstractControl. Du kan legge til i arrayet kun typer av AbstractControl, ikke andre. For å forenkle oppgaven, foretrekk å bruke FormBuilder:

 constructor(private fb: FormBuilder) {}

  createForm() {

    this.myform = this.fb.group({
      firstName: ['', [Validators.required, Validators.minLength(4)]],
      lastName: [],
      gender: ['male'],
      dob: [],
      qualification: [],
      resultList: new FormArray([])
    });
  }

Som du kan se før du fyller resultList FormArray, er det kartlagt til FormGroup:

onSave() {
    let stud: Student = new Student();
    stud.firstName = 'Hello';
    stud.lastName = 'World';
    stud.qualification = 'SD';
    this.studList.push(stud);

    let studFg = this.fb.group({
      firstName: [stud.firstName, [Validators.required, Validators.minLength(4)]],
      lastName: [stud.lastName],
      gender: [stud.gender],
      dob: [stud.dob],
      qualification: [stud.qualification],
    })
     let formArray = this.myform.controls['resultList'] as FormArray;
    formArray.push(studFg);
    console.log(formArray.value)
  }

FormBuilder - Oppretter en AbstractControl fra en brukerspesifisert konfigurasjon.

Det er i hovedsak syntaktisk sukker som forkorter new FormGroup(), new FormControl(), og new FormArray() standardkoden som kan bygge seg opp i større skjemaer.

Også, i HTML formControlName bundet til <p>-element, det er ikke en input og du kan ikke binde til ikke-skjemaelementer som div/p/span...:

 <tbody>
                <tr *ngFor="let item of myform.controls.resultList.controls; let i = index" [formGroupName]="i">
                    <td><p formControlName="firstName"></p></td> <==== Wrong element 
                </tr>
</tbody>

Så jeg tror du bare vil vise de ekstra studentene i tabellen. Deretter itererer du over studList og viser verdien dens i tabellen:

<tbody>
                <tr *ngFor="let item of studList; let i = index" [formGroupName]=i>
                    <td>
                        <p> {{item.firstName}} </p>
                    </td>
                </tr>
</tbody>

Lapper verdi

Vær forsiktig når du oppdaterer array. Fordi patchValue av FormArray oppdaterer verdier etter indeks:

 patchValue(value: any[], options: {onlySelf?: boolean, emitEvent?: boolean} = {}): void {
    value.forEach((newValue: any, index: number) => {
      if (this.at(index)) {
        this.at(index).patchValue(newValue, {onlySelf: true, emitEvent: options.emitEvent});
      }
    });
    this.updateValueAndValidity(options);
  }

Så, koden nedenfor oppdaterer elementet på index=0: Første indekserte verdi av this.myform.controls['resultList'] as FormArray vil bli erstattet med:

let stud1 = new Student();

stud1.firstName = 'FirstName';
stud1.lastName = 'LastName';
stud1.qualification = 'FFF';
formArray.patchValue([stud1]);

Saken din fungerer ikke fordi patchValue krever noen kontroller i array. I ditt tilfelle er det ingen kontroller i array. Se kildekoden.

StackBlitz Demo

Svar #2

Prøv først med disse trinnene og sørg for at du er på riktig vei

Fordi i ditt scenario patcher du objektet til formArray, så du må først analysere det objektet og sjekke om du har importert ReactiveFormsModule i app.module.ts.

Relaterte artikler