Angular 14中实现下拉框联动过滤避免重复项的逻辑方案求助
Angular 14 实现下拉框Z的动态过滤(基于X/Y组合去重)
核心思路
通过维护已添加的X+Y+Z组合集合,实时根据当前选中的X/Y值过滤Z选项,确保相同X/Y组合下不会重复选择Z;删除表格行时同步移除对应限制,恢复Z选项的可选性。
1. 定义数据结构与基础变量
在组件类中先定义接口和初始数据:
import { Component } from '@angular/core'; import { MatTableDataSource } from '@angular/material/table'; // 定义组合接口 interface DrinkCombination { x: string; y: string; z: string; } @Component({ selector: 'app-drink-selector', templateUrl: './drink-selector.component.html', styleUrls: ['./drink-selector.component.css'] }) export class DrinkSelectorComponent { // 原始选项列表 xOptions = ['Juice', 'Milkshake']; yOptions = ['Medium sugar', 'Regular']; zOptions = ['Banana', 'Almond', 'Papaya']; // 当前选中值 selectedX = ''; selectedY = ''; selectedZ = ''; // 已添加的组合集合(用于快速判断重复) addedCombinations = new Set<string>(); // 表格数据源 tableDataSource = new MatTableDataSource<DrinkCombination>([]); // 表格列名 displayedColumns = ['x', 'y', 'z', 'actions']; // 过滤后的Z选项 get filteredZOptions(): string[] { if (!this.selectedX || !this.selectedY) { return [...this.zOptions]; } // 过滤掉当前X/Y组合下已选过的Z值 return this.zOptions.filter(z => { const key = `${this.selectedX}-${this.selectedY}-${z}`; return !this.addedCombinations.has(key); }); } }
2. 模板实现(Angular Material)
<div class="selector-container"> <mat-form-field> <mat-label>X (Drink Type)</mat-label> <mat-select [(value)]="selectedX"> <mat-option *ngFor="let x of xOptions" [value]="x">{{x}}</mat-option> </mat-select> </mat-form-field> <mat-form-field> <mat-label>Y (Sugar Level)</mat-label> <mat-select [(value)]="selectedY"> <mat-option *ngFor="let y of yOptions" [value]="y">{{y}}</mat-option> </mat-select> </mat-form-field> <mat-form-field> <mat-label>Z (Add-on)</mat-label> <mat-select [(value)]="selectedZ" [disabled]="filteredZOptions.length === 0"> <mat-option *ngFor="let z of filteredZOptions" [value]="z">{{z}}</mat-option> </mat-select> </mat-form-field> <button mat-raised-button color="primary" (click)="addCombination()" [disabled]="!selectedX || !selectedY || !selectedZ"> 添加组合 </button> </div> <div class="table-container"> <table mat-table [dataSource]="tableDataSource"> <ng-container matColumnDef="x"> <th mat-header-cell *matHeaderCellDef> Drink Type </th> <td mat-cell *matCellDef="let element"> {{element.x}} </td> </ng-container> <ng-container matColumnDef="y"> <th mat-header-cell *matHeaderCellDef> Sugar Level </th> <td mat-cell *matCellDef="let element"> {{element.y}} </td> </ng-container> <ng-container matColumnDef="z"> <th mat-header-cell *matHeaderCellDef> Add-on </th> <td mat-cell *matCellDef="let element"> {{element.z}} </td> </ng-container> <ng-container matColumnDef="actions"> <th mat-header-cell *matHeaderCellDef> Actions </th> <td mat-cell *matCellDef="let element"> <button mat-icon-button color="warn" (click)="deleteCombination(element)"> <mat-icon>delete</mat-icon> </button> </td> </ng-container> <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr> <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr> </table> </div>
3. 添加与删除逻辑
在组件类中补充addCombination和deleteCombination方法:
addCombination(): void { const combination: DrinkCombination = { x: this.selectedX, y: this.selectedY, z: this.selectedZ }; const key = `${this.selectedX}-${this.selectedY}-${this.selectedZ}`; // 加入集合和表格数据源 this.addedCombinations.add(key); this.tableDataSource.data = [...this.tableDataSource.data, combination]; // 重置选中的Z值 this.selectedZ = ''; } deleteCombination(element: DrinkCombination): void { const key = `${element.x}-${element.y}-${element.z}`; // 从集合中移除对应键 this.addedCombinations.delete(key); // 更新表格数据源 this.tableDataSource.data = this.tableDataSource.data.filter(item => item.x !== element.x || item.y !== element.y || item.z !== element.z ); }
关键说明
- 使用
Set存储已添加的组合键(格式:X-Y-Z),确保O(1)时间复杂度的重复判断,比数组遍历更高效。 - 利用Angular的
getter属性filteredZOptions,在selectedX或selectedY变化时自动重新计算过滤后的Z选项,无需手动订阅值变化。 - 删除操作同时更新
Set和表格数据源,保证过滤逻辑的实时性。
内容的提问来源于stack exchange,提问作者Phoenix
相关产品推荐
相关产品推荐

