select 选项独立于 formArray Angular
select option independent in formArray Angular
晚上好,我有一个问题我正在使用反应式表单,使用 FormArray,我有一个按钮可以根据需要多次添加 2 个选项,问题是选项是 matselects在其中一个 select 中,我使用了一个事件(更改),问题是第一次添加选项时 onchange 工作正常,但是当添加的选项是以前的值的 2 倍以上时 selected in the matselects change 因为创建的select的onchange被重新执行了。
我想知道是否有办法在 formArray
的每次迭代中独立使用该事件
Component.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>
I don't know what I could do or what would you recommend me to solve
my problem, thank you very much
stackblitz 中的代码
Stackblitz
您必须为 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;
}
}
据我所知,您的主要问题是您有一个变量 filtro
,您正试图将其用于 FormArray 中的所有元素。您可以:
- (我的推荐)创建一个自定义
Pure
管道到 return 过滤别墅列表。纯管道只会在值更改时执行,而不是每个绘制周期。
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,我有一个按钮可以根据需要多次添加 2 个选项,问题是选项是 matselects在其中一个 select 中,我使用了一个事件(更改),问题是第一次添加选项时 onchange 工作正常,但是当添加的选项是以前的值的 2 倍以上时 selected in the matselects change 因为创建的select的onchange被重新执行了。 我想知道是否有办法在 formArray
的每次迭代中独立使用该事件Component.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>
I don't know what I could do or what would you recommend me to solve my problem, thank you very much
stackblitz 中的代码 Stackblitz
您必须为 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;
}
}
据我所知,您的主要问题是您有一个变量 filtro
,您正试图将其用于 FormArray 中的所有元素。您可以:
- (我的推荐)创建一个自定义
Pure
管道到 return 过滤别墅列表。纯管道只会在值更改时执行,而不是每个绘制周期。
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
执行 - 在您的组件中创建一个函数,根据数组项的 manzana 过滤别墅(不推荐,因为这会重新计算每个绘制周期)。
*ngFor
时,您将引用此表单控件的值