Angular2:在FormArray的索引1处找不到表单控件

时间:2018-03-10 21:48:33

标签: angular typescript angular2-forms formarray

在运行时,我从JSON对象获取所有记录,并在表单控件中获取值。但是,在表单数组中,我只获得了许多记录中的第一个。

控制台中显示的错误:

  

在FormArray._throwIfControlMissing的索引1处找不到表单控件

JSON对象和错误的图像:

enter image description here

  1. 接口
  2. 
    
    export interface IService {
        ServiceID: number,
        Name: string,
        Staffs: IStaffView[]
    }
    
    export interface IStaffView {
        StaffServiceID: number,
        StaffID: number,
        Name: string
    }
    
    
    

    1. 组件
    2. 
      
      import { Component, OnInit, Input } from '@angular/core';
      import { ActivatedRoute } from '@angular/router';
      import { Location } from '@angular/common';
      import { Observable } from 'rxjs/Rx';
      import { FormBuilder, FormGroup, FormControl, FormArray , Validators } from '@angular/forms';
      
      import { RESTService } from '../../Service/REST.service';
      import { IService, IStaffView } from '../../Model/service.model';
      import { DBOperation } from '../../Shared/enum';
      import { Global } from '../../Shared/global';
      
      @Component({
          selector: 'app-service-detail',
          templateUrl: 'app/Components/service-detail/service-detail.component.html'
      })
      
      export class ServiceDetailComponent implements OnInit {
         
          service: IService;
          services: IService[];
          staffview: IStaffView;
          staffsview: IStaffView[];
      
          serviceFrm: FormGroup;
          Staffs: FormArray;
      
          msg: string;
          indLoading: boolean = false;
          btnTitle: string;
          dbops: DBOperation;
      
          constructor(
              private fb: FormBuilder,
              private _restService: RESTService,
              private location: Location,
              private _route: ActivatedRoute
          ) {
              const id = this._route.snapshot.params['id'];
              if (!id || id == 0) {
                  this.btnTitle = 'Save';
                  this.dbops = DBOperation.create;
              } else {
                  this.btnTitle = 'Edit';
                  this.dbops = DBOperation.update
              }
          }
      
          ngOnInit(): void {
              //this.Staffs = this.fb.array([
              //    this.initStaff()
              //]);
      
      
              this.serviceFrm = this.fb.group({
                  ServiceID: [''],
                  Name: ['', Validators.required],
                  Staffs: this.fb.array([
                      this.initStaff()
                  ])
              });
      
              this.getService();
          }
      
          initStaff() {
              return this.fb.group({
                  StaffServiceID: [''],
                  StaffID: [''],
                  Name: ['']
              });
          }
      
          getService(): void {
              const id = parseInt(this._route.snapshot.params['id']);
              if (id && id > 0) {
                  this.indLoading = true;
                  this._restService.getById('/api/serviceapi/', id)
                      .subscribe(resp => this.serviceFrm.setValue(resp)
                      , error => this.msg = <any>error);
              }
          }
      
      }
      &#13;
      &#13;
      &#13;

      1. HTML代码
      2. &#13;
        &#13;
          <div class="row form-group">
                            <div class="col-md-3">
                                <label for="message-text" class="control-label">Staffs</label>
                            </div>
                            <div formArrayName="Staffs">
                                <div *ngFor="let staff of serviceFrm.controls.Staffs.controls; let i=index" formGroupName="{{i}}">
                                    <div>
                                        <label>Name</label>
                                        <input type="text" class="form-control" formControlName="Name">
                                    </div>
                                </div>
                            </div>
                        </div>
        &#13;
        &#13;
        &#13;

3 个答案:

答案 0 :(得分:9)

上述错误是由致电this.serviceFrm.setValue(resp)https://github.com/angular/angular/blob/master/packages/forms/src/model.ts#L1382)。

引起的
  

此方法执行严格检查,因此如果您尝试,则会抛出错误      设置不存在的控件的值或排除      控制的价值。

您正尝试将3个项目的数组(根据您的快照)分配给FormArray,在索引0处只有一个初始FormGroup,因此在索引1处分配值失败,因为它不存在。

要在修补值之前解决它清空表单数组,请使用patchValue()(接受部分值)而不是setValue(),然后在循环中推送每个值:

getService(): void {
  const id = parseInt(this._route.snapshot.params['id']);
  if (id && id > 0) {
    this.indLoading = true;
    this._restService.getById('/api/serviceapi/, id).subscribe(
      resp => {
        // get form array reference
        const staffs = this.serviceFrm.get('Staffs') as FormArray;
        // empty form array
        while (staffs.length) {
          staffs.removeAt(0);
        }
        // use patchValue instead of setValue
        this.serviceFrm.patchValue(resp);
        // add form array values in a loop
        resp.Staffs.forEach(staff => staffs.push(this.fb.group(staff));
      }, 
      error => this.msg = <any>error
    );
  }
}

答案 1 :(得分:0)

试试这个:

<div class="row form-group">
                    <div class="col-md-3">
                        <label for="message-text" class="control-label">Staffs</label>
                     </div>
                    <div >
                        <div *ngFor="let staff of serviceFrm.controls.Staffs.controls; let i=index" formArrayName="Staffs">
                            <div [formGroupName]="i">
                                <label>Name</label>
                                <input type="text" class="form-control" formControlName="Name">
                            </div>
                        </div>
                    </div>
                </div>

答案 2 :(得分:0)

可以将setControl与FormArrays一起使用。以下代码是Deborah Kurata的示例:

this.productForm = this.fb.group({
productName: ['', [Validators.required,
                       Validators.minLength(3),
                       Validators.maxLength(50)]],
productCode: ['', Validators.required],
starRating: ['', NumberValidators.range(1, 5)],
tags: this.fb.array([]),
description: ''
});

...

// Update the data on the form
this.productForm.patchValue({
    productName: this.product.productName,
    productCode: this.product.productCode,
    starRating: this.product.starRating,
    description: this.product.description
});

// This line makes the array update!
this.productForm.setControl('tags', this.fb.array(this.product.tags || []));