如何在Angular中推送到表单Array([])

时间:2019-08-06 09:45:12

标签: angular typescript rxjs angular-reactive-forms

我有一个动态复选框,可从API获取数据,以下是html文件

<form [formGroup]="form" (ngSubmit)="submit()">
  <label formArrayName="summons" *ngFor="let order of form.controls.summons.controls; let i = index">
    <input type="checkbox" [formControlName]="i">
    {{summons[i].name}}
  </label>

  <div *ngIf="!form.valid">At least one order must be selected</div>
  <br>
  <button [disabled]="!form.valid">submit</button>
</form>

以下是打字稿文件:

interface Item {
  offenceType4: string;
  permSpeed: string;
  actSpeed: string;
  itemAttributes: ItemAttributes;
  offenceLoc: string;
  itemNo: string;
  summonDate: string;
  distCode: string;
  summonType: string;
  hbtlOffndr: string;
  itemAmount: number;
  itemAttributesCount: number;
  summonAmt: string;
  offenceType1: string;
  offenceCode1: string;
  offenceType2: string;
  offenceCode2: string;
  offenceType3: string;
  category: string;
  offenceCode3: string;
  offenceCode4: string;
  respCode: string;
}

interface ItemAttributes {
  attribute5: string;
  attribute4: string;
  attribute7: string;
  attribute6: string;
  attribute1: string;
  attribute3: string;
  attribute2: string;

}
  interface RootObject {
  items: Item[];
  status: Status;
  additionalProperties: AdditionalProperties;
  metadata: Metadata;
}

export class InquiryResponseMultiselectComponent implements OnInit {
  form: FormGroup;
  summons = [];
  data: any[];

  constructor(
    private formBuilder: FormBuilder,
    private inquiryService: InquiryService
  ) {
    this.form = this.formBuilder.group({
      summons: new FormArray([], minSelectedCheckboxes(1)),
    });

     this.getSummon().subscribe(summons => {
      this.summons = summons;
      this.addCheckboxes();
    });
  }

  ngOnInit() {
    this.getSummon();
  }

  getSummon() {
    return this.inquiryService.getData().pipe(map((item: RootObject) => 
  item.items)) ;
  }

  addCheckboxes() {
    this.summons.map(i => {
    const control = new FormControl();
    const formArray = this.form.controls.summons as FormArray;
    formArray.push(control);
    });
  }

我正在从API获得响应以动态化我的复选框,然后,我需要将新控件推到summons FormArray上,但是我却收到了错误消息

  

core.js:9110错误TypeError:无法读取未定义的属性“地图”

如果我不做这样的映射:

  addCheckboxes() {
      const control = new FormControl();
      const formArray = this.form.controls.summons as FormArray;
      formArray.push(control);
  }

我将获得默认的formControl长度等于1,这是我不想要的,需要建议并指导我如何解决这个问题,

2 个答案:

答案 0 :(得分:0)

由于您使用的是formbuilder,因此无需使用FormArray初始化formarray而是使用formbuilder api

   this.form = this.formBuilder.group({
      summons: this.formBuilder.array([]),
    });

示例:https://stackblitz.com/edit/angular-boxw51

答案 1 :(得分:0)

在这里,您在接收数据之前先初始化表单,因此您要尝试更改已经存在的内容,这比通过sratch进行创建要困难得多。
为此,您可以在预订的 内部初始化表单,在此您知道数组应包含哪些元素。

  constructor(
    private formBuilder: FormBuilder,
    private inquiryService: InquiryService
  ) {

    this.inquiryService.getData().subscribe((receivedSummons: RootObject[]) => {
      this.summons = receivedSummons[0].data;

      let formControls = this.summons.items.map((summon, index) => {
        return new FormControl(index === 0);
      });
      this.form = this.formBuilder.group({
        summons: new FormArray(formControls),
      });
      this.addCheckboxes();
    });
  }

这样做可以使您在html表单的开头添加一个条件(*ngIf),以避免在尝试访问尚未初始化的表单时出错:

<form *ngIf="form" [formGroup]="form" (ngSubmit)="submit()">
  <label formArrayName="summons" *ngFor="let order of form.controls.summons.controls; let i = index">
    <input type="checkbox" [formControlName]="i">
    {{summons[i].name}}
  </label>

  <div *ngIf="!form.valid">At least one order must be selected</div>
  <br>
  <button [disabled]="!form.valid">submit</button>
</form>