[英]Angular 2+ Content Projection and Component property binding
[英]Binding a text input to a property in an observable object - Angular 2+
我正在使用 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>
我知道这是不正确的。 我该如何解决这个问题?
问题是你必须知道什么需要什么,期望什么。 我想你想用“Id”、“betslipTeamName”和“stake”(至少你需要Id和stake)制作一个表单数组,而不仅仅是stake。 使用带有数组的 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.ts 就像
@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);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.