如何在 Angular 中从 FormArray 获取数据

How to get data from FormArray in Angular

提问人:MB_18 提问时间:11/15/2023 最后编辑:Yong ShunMB_18 更新时间:11/15/2023 访问量:61

问:

我想定义一个有一些答案的问题。这是我的代码:

  formGroup!:FormGroup;
  answerFormGroup:FormGroup=this.formBuilder.group({
    text: ['d', Validators.required],
    value: [0, Validators.required]
  });
  ngOnInit() {
    this.formGroup = this.formBuilder.group({
      question:['',Validators.required],
      questionType: [1,Validators.required],
      answers: new FormArray([])
    });
   this.questionTypes=this.localDataService.questionType;
   this.addAnswer();
  }

   // convenience getters for easy access to form fields
   get answers() {
    return this.formGroup.controls["answers"] as FormArray;
  }

  addAnswer(){
    this.answers.push(this.formBuilder.group({
      text: ['d', Validators.required],
      value: [0]
    }));
  }

  submit(){
       console.log(JSON.stringify(this.formGroup.value));
  }

但是当我提交表格时,答案值是默认值,并且不会更改。在表单中,我将默认值“d”更改为“b”,它仍然是“d”。结果如下:

{
  "question": "question1",
  "questionType": 1,
  "answers": [
    {
      "text": "d",
      "value": 0
    }
  ]
}

下面是模板:

<form class="question-card" [formGroup]="formGroup">
    <mat-form-field>
        <mat-label>Question</mat-label>
        <input matInput formControlName="question" placeholder="Question">
    </mat-form-field>
    <mat-form-field>
        <mat-label>Type</mat-label>
        <mat-select formControlName="questionTypeControl" (selectionChange)="updateQuestionType($event)">
            @for (item of questionTypes; track item) {
                <mat-option [value]="item.id">
                    <mat-icon>{{item.icon}}</mat-icon> {{item.text}}
                </mat-option>
            }
        </mat-select>
    </mat-form-field>  
    <div [formGroup]="answerFormGroup">
    @for(item of answers.controls; track item){
        <mat-form-field>
            <mat-label>Value</mat-label>
            <input matInput type="text" formControlName="value">
        </mat-form-field>
        <mat-icon class="delete-btn" (click)="deleteAnswer($event)">delete_forever</mat-icon>
        <mat-form-field>
            <mat-label>Text</mat-label>
            <input matInput type="text" formControlName="text">
        </mat-form-field>
    }
    </div>
    <button mat-mini-fab (click)="addAnswer()">
            <mat-icon>add</mat-icon>
    </button>
    <button type="button" (click)="submit()">Submit</button>
</form>
打字稿 angular-material angular-reactive-forms formarray

评论

0赞 Draess 11/15/2023
你能展示一下模板吗?您可能缺少 formControlName 或 formControl 的赋值。
0赞 MB_18 11/15/2023
@Draess 亲爱的德雷斯,我添加了我的模板。

答:

1赞 Yong Shun 11/15/2023 #1

您正在更新 FormGroup 中的控件,但未更新。从这里:textanswerFormGroupformGroup

<div [formGroup]="answerFormGroup">
  ...
</div>

在模板中,您需要拥有 .formGroupformArrayanswers

<form class="question-card" [formGroup]="formGroup">

  ...

  <ng-container formArrayName="answers">
    @for (item of answers.controls; track item; let i = $index) {

      <div [formGroupName]="i">
        <mat-form-field>
          <mat-label>Value</mat-label>
          <input matInput type="text" formControlName="value" />
        </mat-form-field>
        <mat-icon class="delete-btn" (click)="deleteAnswer($event)"
          >delete_forever</mat-icon
        >
        <mat-form-field>
          <mat-label>Text</mat-label>
          <input matInput type="text" formControlName="text" />
        </mat-form-field>
      </div>
    }
  </ng-container>

  ...

</form>

语法是 Angular 17 中的一个新功能,对我来说非常新。如果您正在寻找旧方法:@for

<ng-container formArrayName="answers">
  <ng-container *ngFor="let answer of answers.controls; let i = index">
    <div [formGroupName]="i"> 
    
    <mat-form-field>
      <mat-label>Value</mat-label>
      <input matInput type="text" formControlName="value" />
    </mat-form-field>
    <mat-icon class="delete-btn" (click)="deleteAnswer($event)"
      >delete_forever</mat-icon
    >
    <mat-form-field>
      <mat-label>Text</mat-label>
      <input matInput type="text" formControlName="text" />
    </mat-form-field>
  </div>
    
  </ng-container>
</ng-container>

演示 @ StackBlitz

请注意,您缺少 .questionTypeControlformGroup