首页 > 解决方案 > 具有 Angular 反应形式的依赖下拉列表

问题描述

我对带有依赖下拉列表的 Angular Reactive Forms 有一个奇怪的问题,我确信这是我缺乏知识的结果。

我希望第二个下拉菜单中的选项取决于第一个下拉菜单的设置方式。当第一个下拉列表更改时,设置第二个下拉列表的选项数组,并选择数组中的第一个元素。

这是一个 StackBlitz,我认为它证明了这个问题

如果我在第一个下拉列表中选择“SAT”,我会在第二个下拉列表中看到预期的“Verbal”,但是如果我然后选择“ACT”,第二个下拉列表显示为空,尽管我认为表单字段价值实际上是“英语”,这是我所期望的。

这是我在 StackBlitz 中的 html。

<p>
  Start editing to see some magic happen :)
</p>
<form [formGroup]="testForm" id="testForm">
  <select id="testType" formControlName="testType" (change)="changeTestType()">
    <option *ngFor="let tType of testTypes">{{tType}}</option>
  </select>
  <select id="testName" formControlName="testName">
    <option *ngFor="let tName of currentTestNames">{{tName}}</option>
  </select>
</form>

这是我的这个组件的打字稿文件。

import { Component, VERSION, OnInit } from "@angular/core";
import { FormBuilder, Validators } from "@angular/forms";

@Component({
  selector: "my-app",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.css"]
})
export class AppComponent implements OnInit {
  constructor(private fb: FormBuilder) {}

  testTypes: string[] = ["ACT", "SAT"];

  testNames: Object = {
    ACT: ["English", "Math", "Composite"],
    SAT: ["Verbal", "Math", "Composite", "Evidence Based Read/Write"]
  };

  currentTestType = this.testTypes[0];
  currentTestNames = this.testNames[this.currentTestType];

  testForm = this.fb.group({
    testType: this.currentTestType,
    testName: this.currentTestNames[0]
  });

  // Does nothing for now.
  ngOnInit() {}

  changeTestType() {
    let newTestType = this.testForm.get("testType").value;

    if (newTestType != this.currentTestType) {
      this.currentTestType = newTestType;
      this.currentTestNames = this.testNames[this.currentTestType];

      // Set test name to be the first thing in the testNames array for this test type.
      this.testForm.patchValue({
        testName: this.currentTestNames[0]
      });
    }
  }
}

感谢您的任何建议。也许我使用了错误的生命周期事件来尝试执行此逻辑或遇到其他问题。

更新:

我注意到,如果我使用对象数组或包含多个属性的“任何”类型,并在选项中使用 [ngValue] 并将其设置为整个对象,这似乎会更好地工作,正如其他地方可能推荐的那样。我也想尝试使用 ngValue 但使用字符串数组。

新的 StackBlitz 链接

更新 2:是的,这是另一个使用 ngValue 和字符串数组的测试,它似乎也比我的原始测试工作得更好,该测试具有没有设置 ngValue 的选项,其中值是使用 Angular 插值语法在选项标签之间设置的<option>{{tType}}</option>

StackBlitz 链接

标签: angularreactive-forms

解决方案


@ji102 即使我不知道实际发生了什么。但是我发现了一件事,如果ACT类型名长度超过 3,如下面的一个。

喜欢

`ACT: ["English", "Math", "Composite", "Component"]`

代替

`ACT: ["English", "Math", "Composite"]`

参考:https ://stackblitz.com/edit/angular-ivy-ogzxer?file=src%2Fapp%2Fapp.component.ts

它可以按您的预期工作。


推荐阅读