You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular Material下拉框selectedCategory在ngOnInit中无法更新问题

Angular Material下拉框selectedCategory无法更新的问题排查与解决

问题现象

在ngOnInit钩子中更新Angular Material下拉框绑定值时,仅selectedCategory对应的下拉框无法正常更新;单独更新前三个下拉框(selectedCenter、selectedOrgType、selectedCategory)时一切正常,但更新全部四个下拉框时就会出现问题。

代码片段

组件ngOnInit代码

async ngOnInit() {
    this.isLoading = true;

    await this.assesmentService.fetchCenters().subscribe((data) => {
      this.centers = data.centers;
    });
    await this.assesmentService.fetchDropDownOptions().subscribe((data) => {
      this.dropDownOptions = data.data;

      if (this.sessionData.length > 0) {
        this.selectedCenter = this.sessionData[0].loc_cd;
        this.handleCenterSelected().then(() => {
          this.selectedOrgType = this.sessionData[0].org_type;
          this.handleOrgSelected().then(() => {
            this.selectedCategory = this.sessionData[0].category_cd;
            this.handleCategorySelected().then(() => {
              this.selectedSubCategory = this.sessionData[0].category_sub_cd;
              this.handleSubCategorySelected()
          });
        });
      }
      this.isLoading = false;
    });
  }

对应HTML代码

<div style="display: flex; align-items: center">
            <div class="formDiv">
              <mat-form-field appearance="fill" class="custom-mat-form-field">
                <mat-label>Service Center</mat-label>
                <mat-select
                  [(ngModel)]="selectedCenter"
                  name="center"
                  required
                  (selectionChange)="handleCenterSelected()"
                >
                  <mat-option
                    *ngFor="let center of centers"
                    [value]="center.loc_cd"
                  >
                    {{ center.loc_cd }}
                  </mat-option>
                </mat-select>
              </mat-form-field>
            </div>

            <div class="formDiv">
              <mat-form-field appearance="fill" class="custom-mat-form-field">
                <mat-label>Org Type</mat-label>
                <mat-select
                  [(ngModel)]="selectedOrgType"
                  name="orgType"
                  required
                  (selectionChange)="handleOrgSelected()"
                >
                  <mat-option
                    *ngFor="let orgType of orgTypes"
                    [value]="orgType.value"
                  >
                    {{ orgType.viewValue }}
                  </mat-option>
                </mat-select>
              </mat-form-field>
            </div>
            <div class="formDiv">
              <mat-form-field appearance="fill" class="custom-mat-form-field">
                <mat-label>Category</mat-label>
                <mat-select
                  class="myDropdown"
                  [(ngModel)]="selectedCategory"
                  [(value)]="selectedCategory"
                  name="category"
                  (selectionChange)="handleCategorySelected()"
                >
                  <mat-option
                    *ngFor="let category of categories"
                    [value]="category"
                  >
                    {{ category }}
                  </mat-option>
                </mat-select>
              </mat-form-field>
            </div>

            <div class="formDiv">
              <mat-form-field appearance="fill" class="custom-mat-form-field">
                <mat-label>Sub Category</mat-label>
                <mat-select
                  [(ngModel)]="selectedSubCategory"
                  name="category"
                  required
                  (selectionChange)="handleSubCategorySelected()"
                >
                  <mat-option
                    *ngFor="let subCategory of subCategory"
                    [value]="subCategory"
                  >
                    {{ subCategory }}
                  </mat-option>
                </mat-select>
              </mat-form-field>
            </div>
            <!-- [disabled]="!selectedCenter || !selectedOperation" -->
          </div>

问题原因与解决方法

1. 重复绑定导致的冲突(最直接原因)

Category下拉框同时使用了[(ngModel)]和[(value)]双向绑定,这两个属性功能完全重叠,会导致Angular无法正确处理值的更新逻辑,直接引发选中状态异常。

解决:删除[(value)]="selectedCategory",仅保留[(ngModel)]="selectedCategory":

<mat-select
  class="myDropdown"
  [(ngModel)]="selectedCategory"
  name="category"
  (selectionChange)="handleCategorySelected()"
>

2. await用法错误,异步流程混乱

await无法直接作用于subscribe方法(subscribe返回的是Subscription对象而非Promise),原代码中的两个await根本没有起到等待异步请求完成的作用,会导致后续赋值操作可能在数据未加载完成时执行,引发顺序混乱。

解决:将Observable转为Promise,使用firstValueFrom等待请求完成:

import { firstValueFrom } from 'rxjs';

async ngOnInit() {
    this.isLoading = true;

    // 等待centers接口返回数据
    const centersData = await firstValueFrom(this.assesmentService.fetchCenters());
    this.centers = centersData.centers;

    // 等待下拉选项接口返回数据
    const dropDownData = await firstValueFrom(this.assesmentService.fetchDropDownOptions());
    this.dropDownOptions = dropDownData.data;

    if (this.sessionData.length > 0) {
      this.selectedCenter = this.sessionData[0].loc_cd;
      await this.handleCenterSelected();
      
      this.selectedOrgType = this.sessionData[0].org_type;
      await this.handleOrgSelected();
      
      this.selectedCategory = this.sessionData[0].category_cd;
      await this.handleCategorySelected();
      
      this.selectedSubCategory = this.sessionData[0].category_sub_cd;
      await this.handleSubCategorySelected();
    }
    this.isLoading = false;
  }

3. 数据匹配问题

确保this.sessionData[0].category_cd的值与categories数组中的选项类型和值完全一致:

  • 比如session中存储的是数字1,但categories数组里是字符串"1",mat-select会无法匹配到对应选项;
  • 检查handleOrgSelected()方法是否正确加载了categories数组,确保设置selectedCategory时,categories已经包含对应的选项。

4. Sub Category的笔误(附带修复)

Sub Category的*ngFor循环变量和数组名重复:*ngFor="let subCategory of subCategory",会导致无法渲染选项,改为正确的数组名(比如subCategories):

<mat-option
  *ngFor="let subCategory of subCategories"
  [value]="subCategory"
>
  {{ subCategory }}
</mat-option>

内容的提问来源于stack exchange,提问作者Juan Marino

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 15:07:01