Angular 13 Material多选下拉框结合cdk-virtual-scroll-viewport滚动后丢失选中状态的问题求助
Angular 13 Material多选下拉框结合cdk-virtual-scroll-viewport滚动后丢失选中状态的问题求助
大家好,我最近在做一个Angular项目,用Angular Material的<mat-select multiple>搭配cdk-virtual-scroll-viewport来处理大数据量的下拉多选场景,结果遇到了一个棘手的问题:当我选中几个分支选项后,滚动到下拉框底部再选择新的选项,之前选中的那些选项竟然自动取消了!
我的实现代码如下:
<mat-select multiple [(ngModel)]="selectedBranches" [compareWith]="compareBranches"> <mat-select-trigger> <span *ngIf="selectedBranches.length === 0">Select branches...</span> <span *ngIf="selectedBranches.length === 1">{{ selectedBranches[0].name }}</span> <span *ngIf="selectedBranches.length > 1">{{ selectedBranches.length }} branches selected</span> </mat-select-trigger> <!-- 搜索输入区域 --> <div class="search-container"> <mat-form-field appearance="outline" class="search-field"> <mat-label>Search branches</mat-label> <input matInput [(ngModel)]="searchText" (ngModelChange)="onSearchChange()" /> <mat-icon matSuffix>search</mat-icon> </mat-form-field> </div> <!-- 全选复选框 --> <div style="margin-left: 17px; margin-bottom: 8px; margin-top: 8px;"> <mat-checkbox [checked]="selectAllChecked" [indeterminate]="isIndeterminate()" (change)="toggleSelectAll($event)" > Select All </mat-checkbox> </div> <!-- 虚拟滚动视图 --> <cdk-virtual-scroll-viewport itemSize="48" class="branch-viewport"> <mat-option *cdkVirtualFor="let branch of branchDropdownList; trackBy: trackByBranchId" [value]="branch" > {{ branch.code }} - {{ branch.name }} </mat-option> </cdk-virtual-scroll-viewport> </mat-select>
我已经尝试过的解决思路:
- 实现了
[compareWith]函数,通过对比branch.id来确保选中状态的匹配 - 确认
branchDropdownList中的每个分支对象都是唯一的 - 在
*cdkVirtualFor指令中添加了trackBy,用branch.id作为跟踪标识 - 确保没有不必要地重新赋值
branchDropdownList数组 - 去掉虚拟滚动测试,此时多选的选中状态完全正常
环境信息:
- Angular 13.x
- @angular/material 13.x
- @angular/cdk 13.x
- Tailwind CSS 3.x
期望与实际行为:
- 期望行为:无论滚动下拉框还是加载更多选项,已选中的项都应该保持选中状态
- 实际行为:启用虚拟滚动后,滚动并选择新项时,之前选中的项会丢失选中状态
想请教各位大佬,怎么才能让这个结合了虚拟滚动的Material多选下拉框稳定保留选中状态?有没有推荐的[compareWith]或者trackBy的用法,能避免DOM回收导致选中状态失效?
内容来源于stack exchange
相关产品推荐
相关产品推荐

