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

Angular中*ngFor与*ngIf组合导致Mat-Select选中项文本不显示

问题根源:*ngIf移除DOM vs [hidden]仅隐藏元素

首先明确两个指令的核心区别:

  • *ngIf 是结构性指令,条件不满足时会把对应的<mat-option>完全从DOM树中移除
  • [hidden] 只是通过CSS display: none 隐藏元素,<mat-option>节点仍然留在DOM中

你的场景里,当用*ngIf过滤选项时,如果没特意排除当前下拉框自己的选中值,会导致当前选中的选项也被移除DOM。而Mat-Select需要依赖DOM中的<mat-option>来匹配选中值并渲染对应的文本——没有了对应的DOM节点,自然无法显示选中的文本。

而[hidden]只是把其他下拉框选中的选项藏起来,当前自己选中的选项始终在DOM里,Mat-Select能正常找到并渲染文本。


组件TS代码示例
import { Component } from '@angular/core';
import { FormGroup, FormBuilder } from '@angular/forms';

interface Option {
  id: number;
  label: string;
}

@Component({
  selector: 'app-select-demo',
  templateUrl: './select-demo.component.html',
  styleUrls: ['./select-demo.component.css']
})
export class SelectDemoComponent {
  form: FormGroup;
  options: Option[] = [
    { id: 1, label: '选项A' },
    { id: 2, label: '选项B' },
    { id: 3, label: '选项C' },
    { id: 4, label: '选项D' }
  ];

  constructor(private fb: FormBuilder) {
    this.form = this.fb.group({
      select1: [null],
      select2: [null],
      select3: [null],
      select4: [null]
    });
  }

  // 获取所有已选中的选项ID(排除当前控件的选中值)
  getSelectedIds(excludeControlName: string): number[] {
    const selectedIds: number[] = [];
    Object.keys(this.form.controls).forEach(controlName => {
      if (controlName !== excludeControlName) {
        const value = this.form.get(controlName)?.value;
        if (value) {
          selectedIds.push(value);
        }
      }
    });
    return selectedIds;
  }

  // 判断选项是否需要隐藏(用于[hidden]方案)
  shouldHideOption(optionId: number, excludeControlName: string): boolean {
    const selectedIds = this.getSelectedIds(excludeControlName);
    return selectedIds.includes(optionId);
  }

  // 错误的*ngIf判断逻辑:把所有选中的都排除,包括当前自己的
  shouldShowOptionWrong(optionId: number): boolean {
    const allSelectedIds = Object.values(this.form.controls).map(ctrl => ctrl.value).filter(v => v);
    return !allSelectedIds.includes(optionId);
  }

  // 正确的*ngIf判断逻辑:排除其他控件的选中值,保留当前自己的
  shouldShowOptionCorrect(optionId: number, excludeControlName: string): boolean {
    const selectedIds = this.getSelectedIds(excludeControlName);
    return !selectedIds.includes(optionId);
  }
}

错误的*ngIf实现(选中项不显示)
<form [formGroup]="form">
  <mat-form-field>
    <mat-label>下拉框1</mat-label>
    <mat-select formControlName="select1">
      <!-- 错误:全局过滤所有选中值,当前选中的选项会被移除DOM -->
      <mat-option *ngFor="let opt of options" 
                  *ngIf="shouldShowOptionWrong(opt.id)" 
                  [value]="opt.id">
        {{ opt.label }}
      </mat-option>
    </mat-select>
  </mat-form-field>

  <!-- 其他3个下拉框结构相同,略 -->
</form>

正确的*ngIf实现(可正常显示选中项)
<form [formGroup]="form">
  <mat-form-field>
    <mat-label>下拉框1</mat-label>
    <mat-select formControlName="select1">
      <!-- 正确:仅排除其他下拉框的选中值,保留当前自己的选中项 -->
      <mat-option *ngFor="let opt of options" 
                  *ngIf="shouldShowOptionCorrect(opt.id, 'select1')" 
                  [value]="opt.id">
        {{ opt.label }}
      </mat-option>
    </mat-select>
  </mat-form-field>

  <mat-form-field>
    <mat-label>下拉框2</mat-label>
    <mat-select formControlName="select2">
      <mat-option *ngFor="let opt of options" 
                  *ngIf="shouldShowOptionCorrect(opt.id, 'select2')" 
                  [value]="opt.id">
        {{ opt.label }}
      </mat-option>
    </mat-select>
  </mat-form-field>

  <!-- 下拉框3、4同理替换对应的controlName -->
</form>

[hidden]方案实现(正常显示选中项)
<form [formGroup]="form">
  <mat-form-field>
    <mat-label>下拉框1</mat-label>
    <mat-select formControlName="select1">
      <mat-option *ngFor="let opt of options" 
                  [hidden]="shouldHideOption(opt.id, 'select1')" 
                  [value]="opt.id">
        {{ opt.label }}
      </mat-option>
    </mat-select>
  </mat-form-field>

  <!-- 其他3个下拉框结构相同,替换controlName即可 -->
</form>

总结
  • 若坚持用*ngIf,必须在过滤逻辑中排除当前下拉框自己的选中值,否则选中的选项会被移除DOM,导致Mat-Select无法渲染文本
  • [hidden]方案更简洁,因为它仅隐藏元素不删除DOM,当前选中的选项始终存在,Mat-Select能正常匹配到对应的选项

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 23:33:18