You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular 6中用FormArray实现动态问答表单的单选按钮问题

解决FormArray中单选按钮互斥失效的问题

你的问题根源在于:每个选项的isCorrect控件属于各自的formGroupName,导致原生单选按钮的name属性被Angular自动生成为不同值(比如options-0-isCorrect、options-1-isCorrect),而原生单选按钮只有相同name属性才会触发互斥选中的行为。同时,每个isCorrect是独立的FormControl,切换时不会自动将其他选项的状态置为未选中。

下面提供两种解决方案,你可以根据现有代码情况选择:

方案一:快速修复现有结构

修改HTML

给所有单选按钮设置相同的name属性,并在change事件中传递当前选项的索引:

<form [formGroup]="questionForm">
  <button type="button" class="iconBtn" title="Add Options" (click)="addOptions()"> Add Option </button>
  <div formArrayName="options">
    <div *ngFor="let option of questionForm.controls['options'].controls; let i = index">
      <div class="row" [formGroupName]='i'>
        <div class="col-xs-1 text-right">
          <span class="radio">
            <label class="radio-inline" title="Select if this is correct answer">
              <input type="radio" 
                     [formControlName]="'isCorrect'" 
                     value="1" 
                     name="correctOption"  <!-- 统一name属性 -->
                     (change)="selectCorrectOption(i)"/>  <!-- 传递当前索引 -->
            </label>
          </span>
        </div>
        <div class="col-xs-11">
          <input type="text" class="form-control" placeholder="Option Text" [formControlName]="'optionText'"/>
        </div>
      </div>
    </div>
  </div>
</form>

修改TypeScript

在selectCorrectOption方法中手动遍历所有选项,将选中项的isCorrect设为1,其余设为0:

selectCorrectOption(selectedIndex: number) {
  const optionsArray = this.questionForm.get('options') as FormArray;
  optionsArray.controls.forEach((control, index) => {
    // 给非选中项的isCorrect设为0,选中项设为1
    control.get('isCorrect')?.setValue(index === selectedIndex ? 1 : 0);
  });
}

方案二:重构表单结构(更优)

从业务逻辑来看,正确选项只有一个,没必要给每个选项都单独存储isCorrect状态。我们可以新增一个单独的FormControl来存储正确选项的索引,这样更符合表单设计的合理性:

修改TypeScript

调整表单初始化和添加选项的逻辑:

ngOnInit() {
  this.questionForm = this._fb.group({
    'options': this._fb.array([
      this._fb.group({
        'optionText': ['']
      })
    ]),
    'correctOptionIndex': [0] // 新增控件,存储正确选项的索引
  });
}

public addOptions() {
  let control = <FormArray>this.questionForm.controls.options;
  control.push(this._fb.group({
    'optionText': ['']
  }));
}

修改HTML

让所有单选按钮绑定到correctOptionIndex控件,通过value传递当前选项的索引:

<form [formGroup]="questionForm">
  <button type="button" class="iconBtn" title="Add Options" (click)="addOptions()"> Add Option </button>
  <div formArrayName="options">
    <div *ngFor="let option of questionForm.controls['options'].controls; let i = index">
      <div class="row" [formGroupName]='i'>
        <div class="col-xs-1 text-right">
          <span class="radio">
            <label class="radio-inline" title="Select if this is correct answer">
              <input type="radio" 
                     [value]="i" 
                     [formControl]="questionForm.get('correctOptionIndex')" />
            </label>
          </span>
        </div>
        <div class="col-xs-11">
          <input type="text" class="form-control" placeholder="Option Text" [formControlName]="'optionText'"/>
        </div>
      </div>
    </div>
  </div>
</form>

这种方案的优势在于:

  • 原生单选按钮的互斥行为会自动生效(因为它们绑定到同一个FormControl)
  • 表单数据结构更简洁,后续获取正确选项时只需通过correctOptionIndex找到对应索引的选项即可

内容的提问来源于stack exchange,提问作者OM PRAKASH

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 06:47:04