通过添加多行以反应形式获取一个 select 框变化的依赖值
get dependent values on change of one select box in reactive form with add multiple rows
我想创建具有更多功能的依赖下拉列表。我尝试了以下代码:
基本上流程应该是这样的:
- 在 select 类型上,名称值将出现在与 selected 类型
相关的第二个下拉列表中
- 在 select 个名称值上,将列出与 selected 名称
相关的描述值
有多行,所有行都有自己的类型、名称和描述值。问题是当我用 3 个下拉列表的所有值完成第一行 selection 并单击 add more
然后在第二行我 select 键入更改名称值但它也更改了第一个行值。它不应更改第一行的值。
我不知道如何根据添加的行执行此操作,而且所有值都是从 API 填充的,所以我无法在 stackblits 中调用 api。
我必须假设你的 nameList 和 descList 不是字符串数组,否则是对象数组 (*) 所以我想像
this.nameList = [
{id:1,typeId:1,name:"Name 1"},
{id:2,typeId:1,name:"Name 2"},
{id:3,typeId:2,name:"Name 1"}
];
this.descList = [
{id:1,nameId:1,desc:"Description 1"},
{id:2,nameId:1,desc:"Description 2"},
{id:3,nameId:2,desc:"Description 3"}
];
因此很容易“过滤”选项。但在声明一个 getter 以访问 formArray
之前
get uomArray()
{
return this.productForm.get('uom') as FormArray
}
并更改函数以添加新的 FormGroup
addmore() {
this.uomArray.push(
this.uom()
);
}
看看 .html 是如何变成的。 “formArrayName”单独在 div 中,[formGroupName]="i" 在 div 中你迭代 nad 你得到数组的“值”作为 uomArray.value[i].type
我删除类 更清楚的代码
<form name="productForm" autocomplete="off" [formGroup]="productForm">
<div formArrayName="uom">
<div *ngFor="let item of uomArray.controls; let i = index"
[formGroupName]="i">
{{i+1}}
<select formControlName="type">
<option *ngFor="let list of typeList" [value]="list.tyopeId">
{{ list.typeName }}
</option>
</select>
<select formControlName="name">
<ng-container *ngFor="let list of nameList">
<option *ngIf="list.typeId==uomArray.value[i].type" [value]="list.id">
{{ list.name }}</option>
</ng-container>
</select>
<select formControlName="desc">
<ng-container *ngFor="let list of descList">
<option *ngIf="list.nameId==uomArray.value[i].name" [value]="list.id">
{{ list.desc }}
</option>
</ng-container>
</select>
</div>
</div>
</form>
注意:不要使用表单数组或formGroup的数组“控件”,就像您的this.productForm.controls["uom"]["controls"] //<--WRONG
获取或迭代数组一样,正确的方法是使用 this.productForm.get('uom')
Update 根据你的评论,我需要假设你有一项服务,根据“type”的值,你有一个 nameList 的列表,根据“name”的值" 你有一个 descList 列表。但唯一的方法是你有一个可观察对象数组,实际上是两个(一个用于类型,另一个用于名称),并订阅更改。第一个是转换你的函数 uom()
那么我假设您有一个具有两个功能的数据服务
getNames(res){...}
getDescriptions(res){...}
names$:Observables[]=[];
descriptions$:Observables[]=[];
uom() {
const index=this.uomArray().controls?this.uomArray().controls.length:0
const group=this.formBuilder.group({
type: ["", [Validators.required]],
name: ["", [Validators.required]],
desc: ["", [Validators.required]]
});
names$[index]=group.get('type').valueChange.pipe(
map(res=>this.dataService.getNames(res)
)
descriptions$[index]=group.get('name').valueChange.pipe(
map(res=>this.dataService.getDescriptions(res)
)
return group;
}
并且您使用 pie async
迭代可观察对象
<select formControlName="name">
<option *ngFor="let item of names$[i]|async">{{item}}</option>
</select>
<select formControlName="desc">
<option *ngFor="let item of descriptions$[i]|async">{{item}}</option>
</select>
我想创建具有更多功能的依赖下拉列表。我尝试了以下代码:
基本上流程应该是这样的:
- 在 select 类型上,名称值将出现在与 selected 类型 相关的第二个下拉列表中
- 在 select 个名称值上,将列出与 selected 名称 相关的描述值
有多行,所有行都有自己的类型、名称和描述值。问题是当我用 3 个下拉列表的所有值完成第一行 selection 并单击 add more
然后在第二行我 select 键入更改名称值但它也更改了第一个行值。它不应更改第一行的值。
我不知道如何根据添加的行执行此操作,而且所有值都是从 API 填充的,所以我无法在 stackblits 中调用 api。
我必须假设你的 nameList 和 descList 不是字符串数组,否则是对象数组 (*) 所以我想像
this.nameList = [
{id:1,typeId:1,name:"Name 1"},
{id:2,typeId:1,name:"Name 2"},
{id:3,typeId:2,name:"Name 1"}
];
this.descList = [
{id:1,nameId:1,desc:"Description 1"},
{id:2,nameId:1,desc:"Description 2"},
{id:3,nameId:2,desc:"Description 3"}
];
因此很容易“过滤”选项。但在声明一个 getter 以访问 formArray
之前 get uomArray()
{
return this.productForm.get('uom') as FormArray
}
并更改函数以添加新的 FormGroup
addmore() {
this.uomArray.push(
this.uom()
);
}
看看 .html 是如何变成的。 “formArrayName”单独在 div 中,[formGroupName]="i" 在 div 中你迭代 nad 你得到数组的“值”作为 uomArray.value[i].type
我删除类 更清楚的代码
<form name="productForm" autocomplete="off" [formGroup]="productForm">
<div formArrayName="uom">
<div *ngFor="let item of uomArray.controls; let i = index"
[formGroupName]="i">
{{i+1}}
<select formControlName="type">
<option *ngFor="let list of typeList" [value]="list.tyopeId">
{{ list.typeName }}
</option>
</select>
<select formControlName="name">
<ng-container *ngFor="let list of nameList">
<option *ngIf="list.typeId==uomArray.value[i].type" [value]="list.id">
{{ list.name }}</option>
</ng-container>
</select>
<select formControlName="desc">
<ng-container *ngFor="let list of descList">
<option *ngIf="list.nameId==uomArray.value[i].name" [value]="list.id">
{{ list.desc }}
</option>
</ng-container>
</select>
</div>
</div>
</form>
注意:不要使用表单数组或formGroup的数组“控件”,就像您的this.productForm.controls["uom"]["controls"] //<--WRONG
获取或迭代数组一样,正确的方法是使用 this.productForm.get('uom')
Update 根据你的评论,我需要假设你有一项服务,根据“type”的值,你有一个 nameList 的列表,根据“name”的值" 你有一个 descList 列表。但唯一的方法是你有一个可观察对象数组,实际上是两个(一个用于类型,另一个用于名称),并订阅更改。第一个是转换你的函数 uom()
那么我假设您有一个具有两个功能的数据服务
getNames(res){...}
getDescriptions(res){...}
names$:Observables[]=[];
descriptions$:Observables[]=[];
uom() {
const index=this.uomArray().controls?this.uomArray().controls.length:0
const group=this.formBuilder.group({
type: ["", [Validators.required]],
name: ["", [Validators.required]],
desc: ["", [Validators.required]]
});
names$[index]=group.get('type').valueChange.pipe(
map(res=>this.dataService.getNames(res)
)
descriptions$[index]=group.get('name').valueChange.pipe(
map(res=>this.dataService.getDescriptions(res)
)
return group;
}
并且您使用 pie async
迭代可观察对象<select formControlName="name">
<option *ngFor="let item of names$[i]|async">{{item}}</option>
</select>
<select formControlName="desc">
<option *ngFor="let item of descriptions$[i]|async">{{item}}</option>
</select>