响应式表单的输入数组



我正在努力完成这样的事情

我有一个订阅计划的列表

{ id: 1, data: '1GB', minsms: '5.000', value: 7.5, simCards: 1 },
{ id: 2, data: '3GB', minsms: '5.000', value: 10, simCards: 3 },
{ id: 3, data: '10GB', minsms: '5.000', value: 15, simCards: 2 },
{ id: 4, data: '20GB', minsms: '5.000', value: 20, simCards: 1 },

客户端可以选择每个计划有多少sim卡,我想要放置一个验证(客户端需要选择,即使是零卡)

我试图使用FormArray,但我卡住了。有人能帮帮我吗?

代码(我为这个问题写了一个新代码)https://stackblitz.com/edit/angular-ivy-mwvat5

感谢

在Eliseo的帮助和光照下,我使用formmarray和FormControl在stackblitz上重写了代码

非常感谢https://stackblitz.com/edit/angular-ivy-mwvat5

您有一个计划数组,并且您想要管理一个"simcards"数组。因为你只需要一个输入,你需要一个FormControls的FormArray。

你只需要一个数组(**),所以你可以简单地定义

simCards:FormArray

你可以在。ts中订阅(*)来创建FormArray

plans:any[]
ngOnInit()
{
this._plansService.getPlans().subscribe(res=>{
this.plans=res;
this.simCards=new FormArray(res.map(_=>new FormControl(0)))
})
}
然后创建一个函数来控制formArray
getControl(index)
{
return this.simCards.at(index) as FormControl
}

<!--see that iterate over simCards.controls-->
<mat-form-field *ngFor="let control of simCards.controls;let i=index">
<mat-label
>Num of SIM cards for {{ plans[i].data }} / {{ plans[i].minsms }} at
{{ plans[i].value | currency: 'EUR' }}</mat-label
>
<input matInput type="text" [formControl]="getControl(i)" />
</mat-form-field>

小心,simCars的值只是一个数组"number "(实际上是字符串)所以在submit中你需要写一些像

submit()
{
const values=this.plans.map((x:any,index:number)=>{
id:x.id,
simsCards:this.simCards.value[index]
})
this._plansService.save(values)
}

(*)别忘了退订!

你也可以选择用两个属性创建FormGroups的formmarray: id和simsCards。在这种情况下,可以使用

ngOnInit()
{
this._plansService.getPlans().subscribe(res=>{
this.plans=res;
this.simCards=new FormArray(res.map((x:any)=>new FormGroup({
id:new FormControl(x.id),
simCards:new FormControl(0)
})
))
})
}

创建一个函数getGroup

getGroup(index)
{
return this.simCards.at(index) as FormGroup
}

使用和

<mat-form-field *ngFor="let control of simCards.controls;let i=index" [formGroup]="getGroup(i)">
<mat-label
>Num of SIM cards for {{ plans[i].data }} / {{ plans[i].minsms }} at
{{ plans[i].value | currency: 'EUR' }}</mat-label
>
<input matInput type="text" formControlName="simCards" />
</mat-form-field>

看到了吗,在这个例子中this。simCards。value给了我们一个带有id和simCards的对象数组

最后,如果我们想使用管道异步而不是订阅,我们可以使用"tap"创建formArray

ngOnInit(){
this.plans$ = this._plansService.getPlans().pipe(
tap((plan: Plan[]) => {
this.simCards = new FormArray(
plan.map(
(x: any) =>
new FormGroup({
id: new FormControl(x.id),
simCards: new FormControl(0),
})
)
);
})
);
}

.html与上面的

非常相似
<mat-form-field *ngFor="let plan of plans$ | async;let i=index" [formGroup]="getGroup(i)">
<mat-label
>Num of SIM cards for {{ plan.data }} / {{ plan.minsms }} at
{{ plan.value | currency: 'EUR' }}</mat-label
>
<input matInput type="text" formControlName="simCards" />
</mat-form-field>

注意:你也可以用

的方式定义一个包含FormGroup和formArray的FormGroup
form=new FormGroup({
simCards:new FormArray([])
}) 

和一如既往我们使用FormArray使用getter

get simCards()
{
return this.form.get('simCards') as FormArray
}

这允许我们避免使用函数getGroup()和getControl()在表单

中包含mat-forms如果是FormControls的FormArray

<form [formGroup]="form">
<div formArrayName="simCards">
<mat-form-field
*ngFor="let plan of plans; let i = index" 
>
<mat-label>...</mat-label
>
<input matInput type="text" [formControlName]="i" />
</mat-form-field>
</div>
</form>
ngOnInit()
{
this._plansService.getPlans().subscribe(res=>{
this.plans=res;
this.form=new FormGroup({
simCards:new FormArray(res.map(_=>new FormControl(0)))
})
})
}

如果是FormGroups的FormArray

<form [formGroup]="form">
<div formArrayName="simCards">
<mat-form-field *ngFor="let control of simCards.controls;let i=index"
[formGroupName]="i" >
<label>...</label>
<input matInput formControlName="simCards" type="text" />
</mat-form-field>
</div>
</form>
ngOnInit()
{
this._plansService.getPlans().subscribe(res=>{
this.plans=res;
this.form=new FormGroup({
simCards:new FormArray(res.map((x:any)=>new FormGroup({
id:new FormControl(x.id),
simCards:new FormControl(0)
})
))
})
})
}

如果使用pipe async,我们需要以

的方式将上述表单封装在*ngIf中。
<div *ngIf="{ plan: plans$ | async } as data">
<form [formGroup]="form">
<div formArrayName="simCards">
<mat-form-field
*ngFor="let control of simCards.controls; let i = index"
[formGroupName]="i"
>
<mat-label
>Num of SIM cards for {{ data.plan[i].data }} /
{{ data.plan[i].minsms }} at
{{ data.plan[i].value | currency: 'EUR' }}</mat-label
>
<input matInput type="text" formControlName="simCards" />
</mat-form-field>
</div>
</form>
</div>
this.plans$ = this._plansService.getPlans().pipe(
tap((plan: Plan[]) => {
this.form=new FormGroup({
simCards: new FormArray(
plan.map(
(x: any) =>
new FormGroup({
id: new FormControl(x.id),
simCards: new FormControl(0),
})
)
)
})
})
);

最新更新