我正在构建一个应用程序使用Angular 5,我正在尝试构建一个动态表单。这种形式,就像一个投注单或购物车,是一个对象的数组,来自作为可观察的服务。我很难搞清楚如何添加输入字段并将其绑定到每个下注对象中的属性。
可观察的 betSlipItems 数组如下所示:
[
{
"Id": 1,
"betslipTeamName": "La Rochelle",
"stake": null
},
{
"Id": 2,
"betslipTeamName": "North Queensland Cowboys",
"stake": null
}
]
我想要做的是创建一个输入字段并将其绑定到' 赌注'每个投注对象的属性。
到目前为止,这是 bet-slip.component.ts 的代码:
import { FormBuilder, FormGroup, FormArray } from '@angular/forms';
import { Component, OnInit, Input } from '@angular/core';
import { Bets } from '../../../shared/models';
import { BetService } from '../../../shared/services/bet.service';
import { Observable } from 'rxjs';
import { of } from 'rxjs/observable/of';
@Component({
selector: 'bet-slip',
templateUrl: './bet-slip.component.html',
styleUrls: ['./bet-slip.component.scss']
})
export class BetSlipComponent implements OnInit {
public betSlipItems$: Observable<Bets[]> = of([]);
public betSlipItems: Bets[] = [];
public betsForm: FormGroup;
constructor( private betService: BetService, private _fb: FormBuilder) {
this.betSlipItems$ = this.betService.getBets();
}
ngOnInit() {
this.betsForm = new FormGroup({
stake: new FormControl()
});
this.betSlipItems$.subscribe((betSlipItems) => {
this.betSlipItems = betSlipItems;
});
}
}
我的组件 bet-slip.component.html 如下所示:
<form [formGroup]="betsForm">
<div *ngFor="let bet of betSlipItems; let i=index">
{{bet.betslipTeamName }}
<input type="text" formControlName="stake">
</div>
</form>
我知道这是不正确的,但任何帮助或评论将不胜感激。谢谢!
答案 0 :(得分:1)
@Jose,问题是你必须知道什么是需要和期望。我说你想用&#34; Id&#34;,&#34; betslipTeamName&#34;制作一个表格数组。和&#34;赌注&#34; (最小化你需要Id和赌注)不仅是赌注。要使用带有数组的ReactiveForm,它很容易。通常,我们有一个返回数据的服务。我举了一个完整的例子,我希望这能帮助你
//simple service that read a json (you have one yet -it's only to complete my example-)
@Injectable()
export class AppDataService {
constructor(private httpClient:HttpClient) { }
read(key:any)
{
return this.httpClient.get('../assets/data.json')
}
}
我们的组件有像这样的.html
<div *ngIf="yet">
<!--I put a *ngIf to avoid an error at first-->
<form [formGroup]="dataForm" (ngSubmit)="submit(dataForm)" novalidate>
<!--see that the "formArrayName" is "lista"
don't confuse with the *ngFor of "lista" (the lista in ngFor is a getter)
-->
<div formArrayName="lista" *ngFor="let lista of lista.controls;let i=index">
<div [formGroupName]="i"> <!--it's necesary a formGroupName=i-->
<!--we can use labels here -->
{{labels[i].Id}}{{labels[i].Text}}
<!--the input we need , some can be readOnly -->
<input type="text" class="form-control" formControlName="Id">
<input type="text" class="form-control" formControlName="betslipTeamName">
<input type="text" class="form-control" formControlName="stake">
</div>
<hr>
</div>
</form>
<!---this it's only to check the value of the form-->
{{dataForm?.value |json}}
</div>
组件就像
@Component({
selector: 'app-app-form',
templateUrl: './app-form.component.html',
styleUrls: ['./app-form.component.css']
})
export class AppFormComponent implements OnInit {
dataForm: null | undefined | FormGroup; //we have a dataForm
data: any; //normally we have a data too. It's not necesary that the data was identical to dataFrom
labels:any[] //we create an array [{Id,Text}]
yet:boolean=false; //I use this variable when all it's ready
get lista() { //<--This is the gettet that we use in the *ngFor
return (this.dataForm) ? this.dataForm.get('lista') : null;
};
constructor(private fb: FormBuilder, private dataService: AppDataService) { }
ngOnInit() {
let key: any;
this.dataService.read(key).subscribe(
(response:any[]) => {
if (response) {
this.data = response; //this.data is an array[{"Id": 1,..}.{"Id":2..}]
//You can create a label array with Id,Text
this.labels=response.map((item:any)=>{return {Id:item.Id,Text:item.betslipTeamName}})
this.dataForm = this.createFormGroup(this.data);// dataForms is an object {lista:[{..},{..}]}
this.yet=true;
}
});
}
submit(dataForm:any)
{
if (dataForm.valid)
{
console.log(dataForm.value);
}
}
createFormGroup(data: any) {
let lista = this.buildArray(data); //create an array of Controls
let dataForm = this.fb.group({
lista: lista
});
//see that dataForms is an object {lista:[{..},{..}]}
return dataForm;
}
buildArray(myArray: any[]) {
//witch each data, we create a fbGroup
const arr = myArray.map(data => {
return this.fb.group({
"Id": [data.Id], //we can omit some control
"betslipTeamName": [data.betslipTeamName],
"stake": [data.stake],
});
});
//And return a array of fbGroup
return this.fb.array(arr);
}
}