angular - 通过添加多行以反应形式获取更改一个选择框的相关值
问题描述
我想创建具有添加更多功能的依赖下拉列表。我尝试了以下代码:
基本上这应该是流程:
- 在选择类型时,名称值将在与所选类型相关的第二个下拉列表中
- 在选择名称值时,将列出与所选名称相关的描述值
有多个行,所有行都有自己的类型、名称和描述值。问题是当我使用 3 个下拉列表的所有值完成第一行选择并单击add more
然后在第二行中我选择类型以更改名称值但它也会更改第一行值。它不应该改变第一行的值。
我没有根据添加的行来执行此操作,而且所有值都是从 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中,当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>
注意:不要使用表单数组或表单组的数组“控件”,例如 this.productForm.controls["uom"]["controls"] //<--WRONG
获取或迭代数组,正确的方法是使用this.productForm.get('uom')
根据您的评论更新,我需要假设您有一项服务,根据“type”的值,您有一个 nameList 列表,根据“name”的值,您有一个 descList 列表。但唯一的方法是你有一个可观察的数组,实际上是两个(一个用于类型,另一个用于名称),并订阅更改。第一个是转换你的函数 uom()
我假设您有一个具有两个功能的 dataService
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 遍历 observables
<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>
推荐阅读
- c# - 从一个word文档复制到另一个word文档
- python - Python sqlite3占位符,用于任意长度值的元组
- python - 在 unet 架构中使用自定义权重图的正确方法
- symfony - 带有自定义标签的 Symfony 的 Select2
- c# - c# httpclient 授权标头对我不起作用?
- php - 覆盖来自不同控制器的数组元素 [Codeigniter]
- html - 是否必须将所有内容(即使只是一列)放在行内?
- java - Java - 写return“”是什么意思;在一个方法?
- python - 如何使用pyvmomi获取vm子文件夹对象部署虚拟机
- amazon-web-services - TeamCity 代理 - AWS CLI