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

如何从Angular Material多选框同时获取值与文本?解决重复值问题

解决Angular Material多选时重复添加值与文本的问题

首先,咱们先拆解下你当前代码的核心问题:

  • 每次触发selectionChange时,你只取了event.value[0](第一个选中的值)和第一个选中元素的文本,直接push到数组里——这就导致每次选择都会重复添加,而且完全没处理取消选择的场景。
  • 直接操作DOM获取文本(target.innerText)并不靠谱,Angular的DOM渲染可能会有变化,比如异步加载数据或者模板更新,都可能导致这个方法失效。

推荐解决方案:利用原始数据源匹配(最稳定可靠)

既然你已经有gradeCodes这个数据源,完全可以通过选中的value直接从数据源里匹配对应的Name,不用碰DOM。修改你的selectedGrade方法如下:

selectedGrade(event: any) {
  // 每次选择变化时,根据所有选中的value重新生成selectedLevel数组
  this.selectedLevel = event.value.map(selectedCode => {
    // 从gradeCodes里找到对应的项
    const matchedGrade = this.gradeCodes.find(grade => grade.Code === selectedCode);
    return {
      code: selectedCode,
      level: matchedGrade?.Name?.trim() || ''
    };
  });
}

这个方法的优势:

  1. 完全同步选中状态:不管用户是新增选择还是取消选择,selectedLevel都会自动更新为当前所有选中项的集合,不会有重复。
  2. 不依赖DOM:直接用数据源匹配,避免了DOM结构变化带来的潜在问题。
  3. 代码更简洁,逻辑清晰。

简化模板代码

另外,你模板里的两个span可以简化成一行,用||处理空值:

<mat-form-field appearance="outline">
  <mat-label>Grade</mat-label>
  <mat-select placeholder="Grade" aria-label="Grade" formControlName="Grade" (selectionChange)="selectedGrade($event)" multiple required >
    <mat-option *ngFor="let s of gradeCodes" [value]="s.Code">
      {{ s.Name || ' ' }}
    </mat-option>
  </mat-select>
</mat-form-field>

可选方案:跟踪单个选项的添加/移除(如果需要细粒度控制)

如果你需要单独处理每一次选中/取消的动作(比如记录操作日志),可以通过对比当前选中状态来维护数组:

// 先定义一个变量存储上一次的选中值,初始化为空数组
private previousSelectedValues: any[] = [];

selectedGrade(event: any) {
  const currentSelected = event.value;
  
  // 找出新增的选项:当前有但之前没有的
  const addedValues = currentSelected.filter(code => !this.previousSelectedValues.includes(code));
  // 找出移除的选项:之前有但当前没有的
  const removedValues = this.previousSelectedValues.filter(code => !currentSelected.includes(code));

  // 处理新增
  addedValues.forEach(code => {
    const matchedGrade = this.gradeCodes.find(grade => grade.Code === code);
    this.selectedLevel.push({
      code: code,
      level: matchedGrade?.Name?.trim() || ''
    });
  });

  // 处理移除
  removedValues.forEach(code => {
    const index = this.selectedLevel.findIndex(item => item.code === code);
    if (index > -1) {
      this.selectedLevel.splice(index, 1);
    }
  });

  // 更新上一次的选中值
  this.previousSelectedValues = [...currentSelected];
}

这个方案适合需要跟踪每一步操作的场景,但复杂度比第一种高,推荐优先用第一种方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 22:37:37