如何在Angular Dialog中实现去重可选的Mat Chip List甜点选择功能
实现方案(适配Angular Material v7)
核心调整逻辑
- 移除autocomplete下拉交互,采用「可选预填充可用chip + 已选chip」的双列表方案,完全符合需求
- 新增父传参接收历史已选甜点,全局过滤重复选项
- 禁用用户自定义输入能力,仅允许从预设可用列表选择
1. 父组件弹窗调用调整
调用弹窗时传入已选过的甜点列表,用于过滤重复选项:
// 父组件内已选中的甜点存储在selectedDesserts变量中 this.dialog.open(DessertsComponent, { data: { alreadySelected: this.selectedDesserts } })
2. desserts.component.html 修改
<div mat-dialog-content> <form> <div> <!-- 可用甜点预填充列表 --> <p>可选甜点:</p> <mat-chip-list> <mat-chip *ngFor="let availableDessert of availableDesserts" [selectable]="true" (click)="selectDessert(availableDessert)" > {{availableDessert}} </mat-chip> </mat-chip-list> <!-- 已选甜点列表 --> <mat-form-field appearance="outline" style="margin-top: 16px;"> <mat-label>已选甜点*</mat-label> <mat-chip-list multiple #chipList> <mat-chip *ngFor="let dessert of desserts" [selectable]="selectable" [removable]="removable" (removed)="remove(dessert)" > {{dessert}} <mat-icon matChipRemove *ngIf="removable">cancel</mat-icon> </mat-chip> <!-- 隐藏输入框,禁止自定义输入 --> <input #dessertInput [formControl]="dessertListCtrl" [matChipInputFor]="chipList" style="display: none;" > </mat-chip-list> </mat-form-field> <button mat-button (click)="onSubmit()" [disabled]="desserts.length === 0">Submit</button> </div> </form> </div>
3. desserts.component.ts 修改
import { ENTER, COMMA } from '@angular/cdk/keycodes'; import { Component, ViewChild, ElementRef, Inject } from '@angular/core'; import { FormControl } from '@angular/forms'; import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; import { DBService } from '你的DBService对应引入路径'; export class DessertsComponent{ selectable = true; removable = true; dessertListCtrl = new FormControl(); desserts: string[] = []; // 已选甜点 allDesserts: string[] = []; // 全量甜点列表 availableDesserts: string[] = []; // 过滤后的可用甜点列表 @ViewChild('dessertInput',{static: false}) dessertInput: ElementRef<HTMLInputElement>; constructor( private dbService: DBService, public dialogRef: MatDialogRef<DessertsComponent>, @Inject(MAT_DIALOG_DATA) public data: any, ) { this.dessertsListData(); } dessertsListData(){ this.dbService.dessertsListData().subscribe( (response: string[]) => { this.allDesserts = response; // 过滤掉已经选中过的甜点,得到可用列表 const alreadySelected = this.data?.alreadySelected || []; this.availableDesserts = this.allDesserts.filter(item => !alreadySelected.includes(item)); }); } // 点击可选甜点添加到已选列表 selectDessert(dessert: string) { this.desserts.push(dessert); // 从可用列表移除 const idx = this.availableDesserts.indexOf(dessert); if(idx > -1) { this.availableDesserts.splice(idx, 1); } this.dessertListCtrl.setValue(null); } // 移除已选甜点,加回可用列表 remove(dessert: string): void { const index = this.desserts.indexOf(dessert); if (index >= 0) { this.desserts.splice(index, 1); this.availableDesserts.push(dessert); } } onSubmit(){ this.dialogRef.close({data: this.desserts}); } }
效果说明
- 打开弹窗时自动过滤掉历史已选甜点,不会出现重复选项
- 用户只能点击预设的可用甜点添加,无法自定义输入新增甜点
- 已选甜点可以删除,删除后自动回到可用列表
- 提交时仅返回用户选中的无重复甜点列表,符合存储要求
内容的提问来源于stack exchange,提问作者ng_dev
相关产品推荐
相关产品推荐

