Angular Material 反应形式,根据其他 select 更新 mat-select 选项

Angular Material reactive forms, updating mat-select options based on other select

我目前正在 Angular 6、Material 2 中创建仪表板。(下面列出的版本)

    "dependencies": {
    "@angular/animations": "^6.1.9",
    "@angular/cdk": "^6.4.7",
    "@angular/common": "^6.1.9",
    "@angular/compiler": "^6.1.9",
    "@angular/core": "^6.1.9",
    "@angular/forms": "^6.1.9",
    "@angular/http": "^6.1.9",
    "@angular/material": "^6.4.7",
    "@angular/material-moment-adapter": "^6.4.7",
    "@angular/platform-browser": "^6.1.9",
    "@angular/platform-browser-dynamic": "^6.1.9",
    "@angular/router": "^6.1.9",
    "@types/chart.js": "^2.7.37",
    "chart.js": "^2.7.2",
    "core-js": "^2.5.4",
    "moment": "^2.22.2",
    "rxjs": "^6.3.3",
    "zone.js": "~0.8.26"
  }

我创建了一个表单,用户可以在其中 select 将数据包含在要生成的报告中。

我已经全部使用响应式表单绑定了控件。问题在于两个 mat-select 元素,第二个元素的选项取决于第一个 select 的值。

如果 select1.value === aselect2 将有选项 a_1a_2

如果select1.value === b那么select2将有选项b_1b_2

select2 的值使用

在 HTML 模板中绑定
<mat-option *ngFor="let item of dataSourceSelect.value?.units" [value]="item">{{item.toHTMLString()}}</mat-option>

select1 的值通过 UI 更改时,一切都按预期工作。我遇到的问题是当我使用 FormControl.setValue(obj) 函数更新 mat-select 的值时。我可以更新 select1 的 selected 值就好了,但是不会设置 select2 的值,也不会根据 select1 的值加载选项。

搜索类似案例后,我怀疑 mat-select 的比较器是原因,但是将原始对象传递给 .setValue() 或覆盖 compareWith 函数后的 mat-select 它仍然没有用,所以我想知道是否有人可以帮助我。

我在 Stackblitz

中包含了最少的复制代码

在stackblitz中:改变第一个select的值,你会看到第二个select的选项会改变,然后点击按钮,它使用FormControl.setValue(obj)设置第一个 select 的值,然后第二个 select 根本没有任何选项。

我的方法是使用 valueChanges 属性 dataSourceControl 控件并按预期工作

组件

  ngOnInit() {
    this.reportForm = this.formBuilder.group({
      dataSourceControl: ['', Validators.required],
      dataUnitControl: ['', Validators.required]
    });

    this.reportForm.get('dataSourceControl').valueChanges.subscribe(item => {
      this.units = item.units
    })

模板

<mat-form-field>
  <label for="dataUnitSelect">Data unit: </label>
  <mat-select formControlName="dataUnitControl" required>
    <mat-option *ngFor="let item of units" [value]="item">{{item.toHTMLString()}}</mat-option>
  </mat-select>
  <mat-error *ngIf="reportForm.controls['dataUnitControl'].hasError('required')">Please choose a unit</mat-error>
</mat-form-field>

stackblitz demo

valueChages method return an observable that emits the latest values. You can therefore subscribe to valueChanges to update instance variables or perform operations.