Angular 使用响应式表单的动态单选按钮
Angular Dynamic Radio Buttons using Reactive Forms
我正在开发 Angular 12 应用程序。它有一个 table 动态填充多行。每行有四列。第三列有 radioButton Yes No 如图所示。
- 期望的输出:
例如,如果 table 有三行,我想在第一行 select Yes Radio button,在第二行 No,并且我不想在第三行 select any ,它应该被允许。
- 实际输出:
它让我 select 只有一行是或否。
我的 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 }}"> {{ 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">
我正在开发 Angular 12 应用程序。它有一个 table 动态填充多行。每行有四列。第三列有 radioButton Yes No 如图所示。
- 期望的输出: 例如,如果 table 有三行,我想在第一行 select Yes Radio button,在第二行 No,并且我不想在第三行 select any ,它应该被允许。
- 实际输出: 它让我 select 只有一行是或否。
我的 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 }}"> {{ 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">