将动态表单字段存储为角度数组

问题描述 投票:1回答:2

question.component.ts

   ngOnInit() {
        this.challengeId = this.route.snapshot.paramMap.get('challengeId');
        // this.selectedNoOfAttempt = this.noofattempts[1];
        this.myForm = this._fb.group({
          question: ['', [Validators.required]],
          correctAnswers: this._fb.array([
            this.initCorrectAnswer(),
        ]),
          selectedNoOfAttempt: ['', [Validators.required]]
      });
      }

      initCorrectAnswer() {
        return this._fb.group({
          correctAnswers: ['', Validators.required],
        });
      }

      addAnswer() {
        const control = <FormArray>this.myForm.controls['correctAnswers'];
        control.push(this.initCorrectAnswer());
      }

      removeAnswer(i: number) {
        const control = <FormArray>this.myForm.controls['correctAnswers'];
        control.removeAt(i);
      }

question.component.html

 <div formArrayName="correctAnswers">
    <div *ngFor="let correctAnswers of myForm.controls.correctAnswers.controls; let i=index" class="panel panel-default">
      <div class="panel-heading">
        <span>Answer {{i + 1}}</span>
        <span class="glyphicon glyphicon-remove pull-right" *ngIf="myForm.controls.correctAnswers.controls.length > 1" (click)="removeAnswer(i)">Remove</span>
      </div>
      <div class="panel-body" [formGroupName]="i">
        <div class="form-group col-xs-3">
          <input type="text" class="form-control" formControlName="correctAnswers">
          <small [hidden]="myForm.controls.correctAnswers.controls[i].controls.correctAnswers.valid" class="text-danger">
            Answer is required
          </small>
        </div>
      </div>
    </div>
  </div>
  <div class="margin-20">
    <a (click)="addAnswer()" style="cursor: default">
      Add another answer +
    </a>
  </div>

上面的代码按预期工作,如果需要动态插入更多字段,也可以删除。它还能够返回所有动态字段,但是它将数据存储为

 correctAnswers (array)
           [0]  (object)
             correctAnswers: "test" (string)
           [1]  (object)
             correctAnswers: "abc"  (string)

我想将数据存储如下

 correctAnswers (array)
           [0] "test" (string)
           [1] "abc"  (string)
arrays angular typescript google-cloud-firestore
2个回答
3
投票

initCorrectAnswer()函数中,您将带有子窗体控件的窗体组添加到窗体数组中,这就是您将其视为对象数组的原因。而不是这个,你应该添加表单控件:

initCorrectAnswer() {
  return this._fb.control('', Validators.required);
}

我还添加了correctAnswers getter以便在HTML中使用:

get correctAnswers(): FormArray { 
  return this.myForm.get('correctAnswers') as FormArray; 
}

更新了addremove功能:

addAnswer() {
 this.correctAnswers.push(this.initCorrectAnswer());
}

removeAnswer(i: number) {
  this.correctAnswers.removeAt(i);
}

这是HTML:

<form [formGroup]="myForm">
  <div formArrayName="correctAnswers">
    <div class="panel panel-default" 
         *ngFor="let correctAnswer of correctAnswers.controls; index as i">
      <div class="panel-heading">
        <span>Answer {{i + 1}}</span>
        <span class="glyphicon glyphicon-remove pull-right"
              *ngIf="correctAnswers.controls.length > 1" 
              (click)="removeAnswer(i)">Remove</span>
      </div>
      <div class="panel-body">
        <div class="form-group col-xs-3">
          <input type="text" class="form-control" [formControlName]="i">
          <small [hidden]="correctAnswer.valid" class="text-danger">
            Answer is required
          </small>
        </div>
      </div>
    </div>
  </div>
</form>

StackBlitz:https://stackblitz.com/edit/angular-643srq?file=app%2Fapp.component.html

Official reference


0
投票

你无法通过Angular的反应形式实现它,因为每个重复的形式组(通过你的*ngFor)都是一个对象。请注意,您的表单组名称实际上是您的*ngFor索引:formGroupName = i;并且您的表单控件是correctAnswers - 它对应于您的对象属性,名称为correctAnswers,如您所料。

但是,您可以进行一些后期处理。只需使用数组map()将对象展平为数组:

var flattenedArray = this.myForm.correctAnswers.map(x=>x.correctAnswers);
© www.soinside.com 2019 - 2024. All rights reserved.