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

Angular mat-select多选搜索时已选选项被清除的解决方法

解决Angular多选mat-select搜索后选中项丢失问题

问题根源

你当前代码的核心问题有两个:

  1. 同时混用了formControlName和[(ngModel)],这会导致Angular表单状态管理冲突,是选中项丢失的主要原因。
  2. 将搜索输入框放在了disabled的mat-option内部,这种非常规布局会干扰mat-select对选中状态的正常维护。

解决方案

下面提供两种实现方案,统一解决选中项保留问题,同时优化交互体验:


方案1:使用Reactive Forms(推荐)

完全用FormControl管理选中状态,配合matSelectContent自定义下拉面板布局,避免搜索框干扰选项选中逻辑。

HTML代码:

<mat-select formControlName="services" #searchSelect multiple panelClass="select-with-search">
  <ng-template matSelectContent>
    <!-- 搜索框放在下拉面板顶部,独立于选项之外 -->
    <div class="search-container">
      <input
        type="text"
        [(ngModel)]="searchService"
        [ngModelOptions]="{ standalone: true }"
        placeholder="Rechercher ..."
      />
      <mat-icon>search</mat-icon>
    </div>
    <!-- 过滤后的选项列表 -->
    <mat-option *ngFor="let service of services | filter : searchService" [value]="service.id">
      {{ service.name }}
    </mat-option>
  </ng-template>
</mat-select>

CSS样式(调整搜索框布局):

.select-with-search .mat-select-content {
  padding-top: 0;
}

.search-container {
  display: flex;
  align-items: center;
  padding: 8px 16px;
  border-bottom: 1px solid rgba(0,0,0,0.12);
}

.search-container input {
  flex: 1;
  border: none;
  outline: none;
  font-size: 14px;
}

.search-container mat-icon {
  color: rgba(0,0,0,0.54);
}

TS代码(初始化表单控件):

import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup } from '@angular/forms';

@Component({
  // 你的组件元数据
})
export class YourComponent implements OnInit {
  form: FormGroup;
  services = []; // 替换为你的服务数据数组
  searchService = '';

  constructor(private fb: FormBuilder) {}

  ngOnInit(): void {
    // 初始化多选控件的FormControl,默认空数组
    this.form = this.fb.group({
      services: []
    });
  }
}

方案2:仅使用ngModel

如果项目未使用Reactive Forms,可保留ngModel,但需移除formControlName,并同样调整搜索框布局:

HTML代码:

<mat-select [(ngModel)]="selectedServiceIds" #searchSelect multiple panelClass="select-with-search">
  <ng-template matSelectContent>
    <div class="search-container">
      <input
        type="text"
        [(ngModel)]="searchService"
        [ngModelOptions]="{ standalone: true }"
        placeholder="Rechercher ..."
      />
      <mat-icon>search</mat-icon>
    </div>
    <mat-option *ngFor="let service of services | filter : searchService" [value]="service.id">
      {{ service.name }}
    </mat-option>
  </ng-template>
</mat-select>

TS代码:

import { Component } from '@angular/core';

@Component({
  // 你的组件元数据
})
export class YourComponent {
  selectedServiceIds: number[] = [];
  services = []; // 替换为你的服务数据数组
  searchService = '';
}

关键说明

  • 用matSelectContent自定义下拉面板,将搜索框与选项分离,彻底避免交互冲突。
  • 单一使用FormControl或ngModel管理选中状态,确保表单状态唯一可信。
  • 即使选项被搜索过滤隐藏,FormControl/ngModel仍会保留已选中项的状态,再次搜索显示时会自动恢复选中标记。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 06:15:22