Angular 使用响应式表单的动态单选按钮

Angular Dynamic Radio Buttons using Reactive Forms

我正在开发 Angular 12 应用程序。它有一个 table 动态填充多行。每行有四列。第三列有 radioButton Yes No 如图所示。

我的 html 将被动态填充:marks-input-component.html

<ng-container *ngIf="!!markForm" [formGroup]="markForm">
  <ng-container *ngIf="inputType === inputEnum.RADIO_BUTTON">
    <fieldset>
      <ng-container *ngFor="let item of options">
        <div class="float-left">
          <input type="radio" [formControl]="oneInputControl" id="{{ item.markId }}-{{ item.id }}" [value]="item.id">
          <label for="{{ item.markId }}-{{ item.id }}">&nbsp;{{ item.option }}</label>
        </div>
      </ng-container>
    </fieldset>
  </ng-container>
<br>

我的动态 ts 文件:marks-input-component.ts

export class MarksInputComponent implements OnInit{
  @Input() inputType: string;
  @Input() markId: number;
  @Input() markForm: FormGroup;

  options: MarkOption[];
  
    ngOnInit(): void {
    super.ngOnInit();
    this.initOptions();
    this.connectListeners();
  }
  
    private connectListeners() {
    this.onOneInputChange();
  }

  private onOneInputChange() {
    this.oneInputControl.valueChanges.pipe(
      takeUntil(this.destroyed$),
      tap((value) => {
        const id = parseInt(value);
        if (id) {
          const option = this.options.find(v => v.id === id);
          option ? this.markForm.controls.mark.patchValue(option.mark) : this.markForm.controls.mark.patchValue(undefined);
        } else {
          this.oneInputControl.patchValue(-1, { onlySelf: true, emitEvent: false });
          this.markForm.controls.mark.patchValue(undefined);
        }
      })
    ).subscribe();
  }
  
  get responses() {
    return this.markForm.controls.responses as FormArray;
  }

  get oneInputControl() {
    const f = this.responses.controls[0] as FormGroup;
    return f.controls.markId as FormControl;
  }
  }

html页:标记-component.html

<ng-container *ngFor="let markForm of allMarkForms.controls">
    <ng-container *ngFor="let markResponse of manualMarks; let rowNum = index">
        <ng-container *ngIf="markForm.controls.markId.value === markResponse.markId">
            <tr id="manual-mark-response-row-{{ rowNum }}" }}">
                <td id="mark-id-{{ rowNum }}">{{ markResponse.markIdText }}</td>
                <td id="mark-text-{{ rowNum }}">{{ markResponse.markText }}</td>
                <td id="mark-mark_description-{{ rowNum }}">
                        <!-- marks input component -->
                    <app-dynamic-input
                          [inputType]="markResponse.inputType"
                          [markId]="markResponse.markId"
                          [markForm]="markForm"></app-dynamic-input>
                    
                </td>
                 <td id="mark-mark-{{ rowNum }}">
                    <ng-container *ngIf="markResponse.inputType === inputEnum.RADIO_BUTTON">
                          {{ markForm.controls.mark.value }}
                     </ng-container>
           
                 </td>
            </tr>
        </ng-container>
    </ng-container>
</ng-container>

您将相同的 FormControl 分配给每个输入,因此它们将充当单个输入组。实际上,每个是/否对都需要一个唯一的 FormControl

这是一个包含三个是/否问题的简单表单示例

export class OneComponent {
  myFormGroup = new FormGroup({
    q1: new FormControl(),
    q2: new FormControl(),
    q3: new FormControl(),
  });

  get allControlNames() {
    return Object.keys(this.myFormGroup.controls);
  }
}
<form [formGroup]="myFormGroup">
  <ng-container *ngFor="let controlName of allControlNames">
    <label>
      <input type="radio" [value]="true" [formControlName]="controlName" />
      <span>YES</span>
    </label>
    <label>
      <input type="radio" [value]="false" [formControlName]="controlName" />
      <span>NO</span>
    </label>
    <br />
  </ng-container>
</form>

使用 formControlName="" 到 select 来自封装 FormGroup 的特定 FormControl

在输入类型收音机中,我缺少每个是/否对的唯一名称字段。添加 name="{{ item.markId }}-test" 这对我有用。

<input type="radio" name="{{ item.markId }}-test" [formControl]="oneInputControl" id="{{ item.markId }}-{{ item.id }}" [value]="item.id">