Angular mat-select多选搜索时已选选项被清除的解决方法
解决Angular多选mat-select搜索后选中项丢失问题
问题根源
你当前代码的核心问题有两个:
- 同时混用了
formControlName和[(ngModel)],这会导致Angular表单状态管理冲突,是选中项丢失的主要原因。 - 将搜索输入框放在了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
相关产品推荐
相关产品推荐

