问题 无法将数据修补到FormArray


无法将值修补到FormArray resultList

有人可以解释我,我错过了什么?

TS档案:

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() {
  }
}

模型:

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"
   }
]

3833
2018-04-08 08:19


起源

检查我的答案可能会解决您的问题 - Pranay Rana
这对你有用吗? - Pranay Rana
@PranayRana No. - Santosh Jadi


答案:


根据你的问题,你想添加新的 Student 至 resultList。 首先,你需要知道 FormArray 是一个数组 AbstractControl。 您可以  仅数组的类型 AbstractControl 不是其他的。 简化任务更喜欢使用 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([])
    });
  }

正如你在填充前看到的那样 resultList  FormArray,它被映射到 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  - 创造一个 AbstractControl 来自用户指定的   组态。

它本质上是语法糖缩短了 新FormGroup(),    新的FormControl(),和 新FormArray() 可以建立起来的样板   以更大的形式。

另外,在html中 formControlName 势必 <p> 元素,它不是一个输入,你不能绑定到不像表单元素 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>

所以,我想你只想在表格中显示添加的学生。然后迭代 studList 并在表格中显示它的价值:

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

修补价值

修补阵列时要小心。因为 patchValue 的 FormArray 补丁值由 指数

 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);
  }

所以,它下面的代码补丁元素 索引= 0:第一个索引值 this.myform.controls['resultList'] as FormArray 将被替换为:

let stud1 = new Student();

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

你的情况不起作用,因为patchValue 要求 一些 控制 在数组中。在您的情况下,数组中没有控件。看源代码。

StackBlitz演示


7
2018-04-14 15:35



好例子。这应该工作。如果你有时间看看: stackoverflow.com/questions/49666593/... - Swoox


你必须这样,代码取自 angular.io,你需要做setcontrol,它会做或通过链接有相同的代码,它使用地址数组

 this.setAddresses(this.hero.addresses);

  setAddresses(addresses: Address[]) {
    const addressFGs = addresses.map(address => this.fb.group(address));
    const addressFormArray = this.fb.array(addressFGs);
    this.heroForm.setControl('secretLairs', addressFormArray);
  }

2
2018-04-10 12:31





首先尝试这个步骤,确保你正确的方式

因为在您的场景中,您正在将对象修补为formArray,因此您必须首先解析该对象,并在app.module.ts中导入ReactiveFormsModule时检查一次。


2
2018-04-16 10:03





数组不包含 patchValue 方法。你必须迭代控件和 patchValue  他们每个人分开。


1
2018-04-08 08:35



你能用样例来解释吗? - Santosh Jadi
@ritaj,错了。 FormArray有方法 patchValue  例 和 源代码 - Yerkon