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)
答案 0 :(得分:3)
在initCorrectAnswer()
函数中,您将带有子窗体控件的窗体组添加到窗体数组中,这就是您将其视为对象数组的原因。而不是这个,你应该添加表单控件:
initCorrectAnswer() {
return this._fb.control('', Validators.required);
}
我还添加了correctAnswers
getter 以便在HTML中使用:
get correctAnswers(): FormArray {
return this.myForm.get('correctAnswers') as FormArray;
}
更新了add
和remove
个功能:
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
答案 1 :(得分:0)
你无法通过Angular的反应形式来实现它,因为每个重复的表单组(通过你的*ngFor
)都是一个对象。请注意,您的表单组名称实际上是您的*ngFor
索引:formGroupName = i
;并且您的表单控件为correctAnswers
- 与您预期的名称为correctAnswers
的对象属性相对应。
但是,您可以进行一些后期处理。只需使用数组map()
将对象展平为数组:
var flattenedArray = this.myForm.correctAnswers.map(x=>x.correctAnswers);