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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 02:15:08