Angular 带有单选按钮的反应式表单数组
Angular Reactive Form Array with Radio Buttons
我对响应式表单和一组单选按钮有疑问。
我的表单如下所示:
连续有一个玩家,我要选择状态
组件:
<tr *ngFor="let data of player">
<th>{{data.firstname}} {{data.lastname}}</th>
<th *ngFor="let stat of status">
<input type="radio" id="opt1+{{data.id}}" value="{{stat}}" name="option+{{data.id}}" formArrayName="status???"></th>
</tr>
玩家数据来自一个API,status是一个数组。
ts:
this.myForm = formBuilder.group({
status: this.formBuilder.array,
})
我的示例不起作用。
结果我需要一个 json 文件。 (玩家名 + 状态,例如现在)
我找不到实现它的方法。
有什么提示吗?
也许你可以不使用表格来完成。
基本上有一个像这样的 html 设置,使用 ngModel 设置状态:
<table>
<tr>
<th>Firstname</th>
<th>present</th>
<th>missing</th>
<th>apologizes</th>
<th>unexcused</th>
</tr>
<tr *ngFor="let data of player">
<th>{{data.firstname}} {{data.lastname}}</th>
<th *ngFor="let stat of status">
<input type="radio" id="opt1+{{data.id}}" [(ngModel)]="data.status" value="{{stat}}" name="option+{{data.id}}">
</th>
</tr>
</table>
以及获取所需数据的简单函数:
getJsonResult() {
alert(JSON.stringify(this.player.map(x => {
return {
playername: x.firstname + ' ' + x.lastname,
status: x.status
}
})));
}
stackblitz 上的工作示例。
更新
ReactiveForm 方式需要更多代码。首先是一个 FormGroup,然后是一个带有玩家的 FormArray。 formArrayName="players"
<form (ngSubmit)="onSubmit()" [formGroup]="playersForm">
<table border="1">
<tr>
<th>Firstname</th>
<th>present</th>
<th>missing</th>
<th>apologizes</th>
<th>unexcused</th>
</tr>
<tr formArrayName="players" *ngFor="let data of playersForm.get('players').controls; let i = index">
<ng-container [formGroupName]="i">
<th>
<input type="text" formControlName="name" readonly>
</th>
<th *ngFor="let stat of status">
<input type="radio" formControlName="status" value="{{stat}}">
</th>
</ng-container>
</tr>
</table>
<br>
<button type="submit">Submit</button>
</form>
Typescript 部分将构建并填充数组。
playersForm: FormGroup;
constructor(private fb: FormBuilder) { }
ngOnInit(): void {
this.playersForm = this.fb.group({
players: this.fb.array([])
});
this.player.forEach(p => {
(this.playersForm.get('players') as FormArray).push(
this.addPlayerFormGroup(p.firstname + ' ' + p.lastname, '')
);
});
}
private addPlayerFormGroup(name?: string, status?: string): FormGroup {
return this.fb.group({
name,
status
});
}
onSubmit() {
alert(JSON.stringify(this.playersForm.value));
}
在app.moudule.ts
import { ReactiveFormsModule } from '@angular/forms';
而不是 FormsModule。
新工作stackblitz.
第二次更新
正如@Eliseo 建议的那样,您可以在不嵌套 FormArray 的情况下完成。
ngOnInit(): void {
this.playersForm = this.fb.array([]);
this.player.forEach(p => {
this.playersForm.push(
this.addPlayerFormGroup(p.firstname + ' ' + p.lastname, '')
);
});
}
html:
<tr *ngFor="let fg of playersForm.controls; index as i">
<td>
<input type="text" [formControl]="fg.get('name')" readonly>
</td>
<td *ngFor="let stat of status">
<input type="radio" id="opt1+{{player[i].id}}" value="{{stat}}" name="option+{{player[i].id}}"
[formControl]="fg.get('status')">
</td>
第三次更新
如果您有来自可观察对象的数据,请考虑以下方法。我正在使用 SWAPI 获取一些数据。一旦你收到数据。您可以将原始数据映射到所需的格式,然后调用一个方法来填充 FormArray。
ngOnInit(): void {
this.playersForm = this.fb.array([]);
let counter = 0;
const apiUrl = 'https://swapi.co/api/people';
this.http.get(apiUrl).subscribe((peoples: any) => {
this.player = peoples.results.map(p => {
return {
id: ++counter,
name: p.name,
staus: null
}
})
this.populateForm();
});
}
private populateForm() {
this.player.forEach(p => {
this.playersForm.push(
this.addPlayerFormGroup(p.name, '')
);
});
}
我对响应式表单和一组单选按钮有疑问。
我的表单如下所示:
连续有一个玩家,我要选择状态
组件:
<tr *ngFor="let data of player">
<th>{{data.firstname}} {{data.lastname}}</th>
<th *ngFor="let stat of status">
<input type="radio" id="opt1+{{data.id}}" value="{{stat}}" name="option+{{data.id}}" formArrayName="status???"></th>
</tr>
玩家数据来自一个API,status是一个数组。
ts:
this.myForm = formBuilder.group({
status: this.formBuilder.array,
})
我的示例不起作用。 结果我需要一个 json 文件。 (玩家名 + 状态,例如现在) 我找不到实现它的方法。 有什么提示吗?
也许你可以不使用表格来完成。
基本上有一个像这样的 html 设置,使用 ngModel 设置状态:
<table>
<tr>
<th>Firstname</th>
<th>present</th>
<th>missing</th>
<th>apologizes</th>
<th>unexcused</th>
</tr>
<tr *ngFor="let data of player">
<th>{{data.firstname}} {{data.lastname}}</th>
<th *ngFor="let stat of status">
<input type="radio" id="opt1+{{data.id}}" [(ngModel)]="data.status" value="{{stat}}" name="option+{{data.id}}">
</th>
</tr>
</table>
以及获取所需数据的简单函数:
getJsonResult() {
alert(JSON.stringify(this.player.map(x => {
return {
playername: x.firstname + ' ' + x.lastname,
status: x.status
}
})));
}
stackblitz 上的工作示例。
更新
ReactiveForm 方式需要更多代码。首先是一个 FormGroup,然后是一个带有玩家的 FormArray。 formArrayName="players"
<form (ngSubmit)="onSubmit()" [formGroup]="playersForm">
<table border="1">
<tr>
<th>Firstname</th>
<th>present</th>
<th>missing</th>
<th>apologizes</th>
<th>unexcused</th>
</tr>
<tr formArrayName="players" *ngFor="let data of playersForm.get('players').controls; let i = index">
<ng-container [formGroupName]="i">
<th>
<input type="text" formControlName="name" readonly>
</th>
<th *ngFor="let stat of status">
<input type="radio" formControlName="status" value="{{stat}}">
</th>
</ng-container>
</tr>
</table>
<br>
<button type="submit">Submit</button>
</form>
Typescript 部分将构建并填充数组。
playersForm: FormGroup;
constructor(private fb: FormBuilder) { }
ngOnInit(): void {
this.playersForm = this.fb.group({
players: this.fb.array([])
});
this.player.forEach(p => {
(this.playersForm.get('players') as FormArray).push(
this.addPlayerFormGroup(p.firstname + ' ' + p.lastname, '')
);
});
}
private addPlayerFormGroup(name?: string, status?: string): FormGroup {
return this.fb.group({
name,
status
});
}
onSubmit() {
alert(JSON.stringify(this.playersForm.value));
}
在app.moudule.ts
import { ReactiveFormsModule } from '@angular/forms';
而不是 FormsModule。
新工作stackblitz.
第二次更新
正如@Eliseo 建议的那样,您可以在不嵌套 FormArray 的情况下完成。
ngOnInit(): void {
this.playersForm = this.fb.array([]);
this.player.forEach(p => {
this.playersForm.push(
this.addPlayerFormGroup(p.firstname + ' ' + p.lastname, '')
);
});
}
html:
<tr *ngFor="let fg of playersForm.controls; index as i">
<td>
<input type="text" [formControl]="fg.get('name')" readonly>
</td>
<td *ngFor="let stat of status">
<input type="radio" id="opt1+{{player[i].id}}" value="{{stat}}" name="option+{{player[i].id}}"
[formControl]="fg.get('status')">
</td>
第三次更新
如果您有来自可观察对象的数据,请考虑以下方法。我正在使用 SWAPI 获取一些数据。一旦你收到数据。您可以将原始数据映射到所需的格式,然后调用一个方法来填充 FormArray。
ngOnInit(): void {
this.playersForm = this.fb.array([]);
let counter = 0;
const apiUrl = 'https://swapi.co/api/people';
this.http.get(apiUrl).subscribe((peoples: any) => {
this.player = peoples.results.map(p => {
return {
id: ++counter,
name: p.name,
staus: null
}
})
this.populateForm();
});
}
private populateForm() {
this.player.forEach(p => {
this.playersForm.push(
this.addPlayerFormGroup(p.name, '')
);
});
}