首页 > 解决方案 > 通过添加多行以反应形式获取更改一个选择框的相关值

问题描述

我想创建具有添加更多功能的依赖下拉列表。我尝试了以下代码:

堆栈闪电战

基本上这应该是流程:

  1. 在选择类型时,名称值将在与所选类型相关的第二个下拉列表中
  2. 在选择名称值时,将列出与所选名称相关的描述值

有多个行,所有行都有自己的类型、名称和描述值。问题是当我使用 3 个下拉列表的所有值完成第一行选择并单击add more然后在第二行中我选择类型以更改名称值但它也会更改第一行值。它不应该改变第一行的值。

我没有根据添加的行来执行此操作,而且所有值都是从 API 填充的,因此我无法在 stackblits 中调用 api。

标签: angulartypescriptdependenciesdropdownangular-reactive-forms

解决方案


我必须假设您的 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>

推荐阅读