如何从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() || '' }; }); }
这个方法的优势:
- 完全同步选中状态:不管用户是新增选择还是取消选择,
selectedLevel都会自动更新为当前所有选中项的集合,不会有重复。 - 不依赖DOM:直接用数据源匹配,避免了DOM结构变化带来的潜在问题。
- 代码更简洁,逻辑清晰。
简化模板代码
另外,你模板里的两个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
相关产品推荐
相关产品推荐

