在 formArray Angular 中选择独立的选项
Posted
技术标签:
【中文标题】在 formArray Angular 中选择独立的选项【英文标题】:select option independent in formArray Angular 【发布时间】:2022-01-13 01:25:34 【问题描述】:晚上好,我有一个问题,我使用的是反应式表单,使用 FormArray,我有一个按钮可以根据需要多次添加 2 个选项,问题是这些选项是 matselects,我在其中一个选择中使用一个事件(更改),问题是第一次添加选项 onchange 工作正常,但是当添加选项超过 2 倍时,之前在 matselects 中选择的值会发生变化,因为创建的 select 的 onchange 是 re -执行。 我想知道是否有办法在 formArray 的每次迭代中独立使用该事件
组件.ts
alicuotaForm: FormGroup;
value = this.fb.group(
manzana: ['', Validators.required],
villa: ['', Validators.required],
);
nregistros: number;
ngOnInit()
this.alicuotaForm = this.fb.group(
times: this.fb.array([]),
);
//event onchange
getVillas(value)
console.log('valor: ', value.value);
this.filtro = this.villas.filter((x) => x.manzana == value.value);
addGroup()
const val = this.fb.group(
manzana: ['', Validators.required],
villa: ['', Validators.required],
);
const alicuotaForm = this.alicuotaForm.get('times') as FormArray;
alicuotaForm.push(val);
this.nregistros = alicuotaForm.length;
removeGroup(index)
const alicuotaForm = this.alicuotaForm.get('times') as FormArray;
alicuotaForm.removeAt(index);
trackByFn(index: any, item: any)
return index;
component.html
<div class="container">
<div class="row">
<div class="col-col-6">
<label class="transparente"></label>
<button (click)="addGroup()" type="button" class="btn btn-success">
Agregar Campos
</button>
</div>
<br />
<form [formGroup]="alicuotaForm">
<ng-container
formArrayName="times"
*ngFor="
let time of alicuotaForm.controls.times?.value;
let i = index;
trackBy: trackByFn
"
>
<ng-container [formGroupName]="i" style="margin-bottom: 10px;">
Iteracion i + 1
<div class="col-col-6">
<label>Manzana</label>
<select
formControlName="manzana"
class="form-control custom-select"
(change)="getVillas($event.target)"
>
>
<option *ngFor="let ur of manzanas">
ur.manzana
</option>
</select>
</div>
<br />
<div class="col-sm">
<label>Villa</label>
<select formControlName="villa" class="form-control custom-select">
<option *ngFor="let ur of filtro" value=" ur.villa ">
ur.villa
</option>
</select>
</div>
<br />
------------------------------------------------------------------------<br /> </ng-container
></ng-container>
</form>
</div>
</div>
我不知道我能做什么或者你会建议我解决什么 我的问题,非常感谢
stackblitz 中的代码 Stackblitz
【问题讨论】:
【参考方案1】:您必须为 filtro 创建单独的值,您可以从以下代码中获得帮助
HTML
<hello name=" name "></hello>
<p>Start editing to see some magic happen :)</p>
<div class="container">
<div class="row">
<div class="col-col-6">
<label class="transparente"></label>
<button (click)="addGroup()" type="button" class="btn btn-success">
Agregar Campos filtro
</button>
</div>
<br />
<form [formGroup]="alicuotaForm">
<ng-container
formArrayName="times"
*ngFor="
let time of alicuotaForm.controls.times?.value;
let i = index;
trackBy: trackByFn
"
>
<ng-container [formGroupName]="i" style="margin-bottom: 10px;">
Iteracion i + 1
<div class="col-col-6">
<label>Manzana</label>
<select
formControlName="manzana"
class="form-control custom-select"
(change)="getVillas($event.target, i)"
>
>
<option *ngFor="let ur of manzanas">
ur.manzana
</option>
</select>
</div>
<br />
<div class="col-sm">
<label>Villa</label>
<select formControlName="villa" class="form-control custom-select">
<option *ngFor="let ur of filtro[i]" value=" ur.villa ">
ur.villa
</option>
</select>
</div>
<br />
------------------------------------------------------------------------<br /> </ng-container
></ng-container>
</form>
打字稿
import Component, VERSION from '@angular/core';
import
FormControl,
FormGroup,
FormBuilder,
FormArray,
Validators,
FormGroupDirective,
from '@angular/forms';
@Component(
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
)
export class AppComponent
name = 'Angular ' + VERSION.major;
villas = [
manzana: '1', villa: '10' ,
manzana: '1', villa: '20' ,
manzana: '1', villa: '30' ,
manzana: '2', villa: '40' ,
manzana: '2', villa: '50' ,
manzana: '2', villa: '60' ,
manzana: '3', villa: '70' ,
manzana: '3', villa: '80' ,
manzana: '3', villa: '90' ,
];
filtro: any[]=[];
manzanas = [ manzana: '1' , manzana: '2' , manzana: '3' ];
alicuotaForm: FormGroup;
value = this.fb.group(
manzana: ['', Validators.required],
villa: ['', Validators.required],
);
nregistros: number;
constructor(private fb: FormBuilder)
ngOnInit()
this.alicuotaForm = this.fb.group(
times: this.fb.array([]),
);
getVillas(value,index)
console.log('valor: ', value.value);
this.filtro[index] = this.filtro[index].filter(x => x.manzana === value.value);
addGroup()
const val = this.fb.group(
manzana: ['', Validators.required],
villa: ['', Validators.required],
);
const alicuotaForm = this.alicuotaForm.get('times') as FormArray;
alicuotaForm.push(val);
this.nregistros = alicuotaForm.length;
this.filtro.push(null);
this.filtro[this.nregistros-1]=[...this.villas];
removeGroup(index)
const alicuotaForm = this.alicuotaForm.get('times') as FormArray;
alicuotaForm.removeAt(index);
trackByFn(index: any, item: any)
return index;
【讨论】:
【参考方案2】:据我所知,您的主要问题是您有一个变量filtro
,您试图将其用于FormArray 中的所有元素。您可以:
-
(我推荐)创建自定义
Pure
管道以返回过滤后的别墅列表。纯管道只会在值发生变化时执行,而不是在每个绘制周期中执行。
import Pipe, PipeTransform from '@angular/core';
@Pipe( name: 'arrayFilter' )
export class ArrayFilterPipe implements PipeTransform
transform(arr: any[], property: string, value: any): any
return arr.filter((x) => x[property] === value);
然后你在你的模板中使用它(不要忘记在你的模块中声明它):
<select formControlName="villa" class="form-control custom-select">
<option
*ngFor="let ur of (villas | arrayFilter: 'manzana': time.manzana)"
value=" ur.villa "
>
ur.villa
</option>
</select>
打字稿:
addGroup()
// either provide a '' option to this.manzanas, or set manzana: '1' to avoid expression after checked errors
const val = this.fb.group(
manzana: ['1', Validators.required],
villa: ['', Validators.required],
);
const alicuotaForm = this.alicuotaForm.get('times') as FormArray;
alicuotaForm.push(val);
this.nregistros = alicuotaForm.length;
有关详细信息,请参阅Pipes。
-
在您的组上创建另一个名为
filtro
的表单控件,并在getVillas
函数中设置它的值。然后,当您为表单控件 villa
执行 *ngFor
时,您将引用此表单控件的值
在您的组件中创建一个函数,根据数组项的 manzana 过滤别墅(不推荐,因为这会重新计算每个绘制周期)。
【讨论】:
以上是关于在 formArray Angular 中选择独立的选项的主要内容,如果未能解决你的问题,请参考以下文章
无法根据角度formarray下拉选择显示/隐藏div [关闭]
FormArray 和 formGroup 中的 Angular Material mat-select
如何在 FormArray 中设置 FormControl 的值
在 Angular 2+ 中对 FormArray 对象进行排序的理想方法是啥?