Angular响应式表单:循环单选框的formControlName绑定及提交问题
Hey there! Let's work through this issue together. The main problems you're facing are:
- All radio buttons are linked to the same
ratingFormcontrol, so selecting one value checks every radio group - You need to collect both the selected value (or text input) and its corresponding question ID when submitting the form
Here's how to fix this step by step:
1. 重构表单为FormArray
Since you're dealing with a dynamic list of questions, we need to use a FormArray instead of a single FormGroup. Each question will have its own nested FormGroup to store the question ID and user's response.
Update your component TypeScript code like this:
import { Component } from '@angular/core'; import { FormBuilder, FormGroup, FormArray, Validators } from '@angular/forms'; @Component({ selector: 'my-app', templateUrl: './app.component.html', styleUrls: ['./app.component.css'], providers: [FormBuilder] }) export class AppComponent { name = 'Angular'; ipdForm: FormGroup; IpdData = []; response = { "data": [{ "id": 19, "question" : "question 1", "options": "radio" }, { "id": 20, "question" : "question 2", "options": "radio" }, { "id": 33, "question" : "question 3", "options": "text" }, { "id": 34, "question" : "question 4", "options": "text" }] }; constructor(private fb: FormBuilder) {} ngOnInit() { this.getIpdFormData(); this.initForm(); } getIpdFormData() { this.IpdData = this.response.data; } initForm() { // Create a FormArray where each element is a FormGroup for a question const questionControls = this.IpdData.map(question => this.fb.group({ questionId: [question.id], // Store the question ID response: ['', Validators.required] // Store user's response (radio or text) })); this.ipdForm = this.fb.group({ questions: this.fb.array(questionControls) }); } ipdFeedback() { // Extract the data in the format you need const formData = this.ipdForm.value.questions.map(item => ({ value: item.response, questionId: item.questionId })); console.log(formData); // Now you can submit formData to your backend } // Helper getter to access the FormArray easily get questionsArray(): FormArray { return this.ipdForm.get('questions') as FormArray; } }
2. 更新模板绑定
Modify your HTML template to connect with the FormArray and each nested FormGroup. This ensures each question's inputs are bound to their own control:
<form class="custom-form" [formGroup]="ipdForm" (submit)="ipdFeedback();"> <!-- Bind to the FormArray --> <div formArrayName="questions"> <!-- Loop through the FormArray controls and IpdData together --> <div class="form-group" *ngFor="let ctrl of questionsArray.controls; let i = index" [formGroupName]="i"> <label class="control-label"> {{IpdData[i].question }} <sup class="custom-required">*</sup> </label> <!-- Radio button group --> <div *ngIf="IpdData[i].options == 'radio'"> <label class="radio-inline custom-radio"> <input class="radio-text" formControlName="response" type="radio" value="Poor" /> <span class="radio-text">Poor</span> </label> <label class="radio-inline custom-radio"> <input class="radio-text" formControlName="response" type="radio" value="Fair" /> <span class="radio-text">Fair</span> </label> <label class="radio-inline custom-radio"> <input class="radio-text" formControlName="response" type="radio" value="Good" /> <span class="radio-text">Good </span> </label> </div> <!-- Text area for text inputs --> <div *ngIf="IpdData[i].options == 'text'"> <textarea placeholder="Comments" formControlName="response" class="form-control" tabindex="14"></textarea> </div> </div> </div> <button type="submit">Submit Feedback</button> </form>
关键改动说明
- FormArray替代单一控件: Each question now has its own FormGroup with
questionId(fixed to the question's ID) andresponse(user's input/selection). This keeps each question's data independent. - 模板中的FormArray绑定: Using
formArrayName="questions"and[formGroupName]="i"ensures each input is linked to the correct control in the array. - 提交数据格式化: The
ipdFeedbackfunction maps the FormArray values directly into your desired[{value:"good",questionId:20}]format.
Now when you select a radio button for one question, it won't affect the others, and submitting the form will give you the structured array you need!
内容的提问来源于stack exchange,提问作者vinuta

