mat-button-toggle多选场景下All/None选项互斥实现方法
逻辑规则
直接按交互要求定死判断规则,覆盖所有边界场景:
- 特殊选项
All、None与普通数值选项(1/2/3)完全互斥,两个特殊选项之间也互斥 - 点击
None时:清空所有已选中的其他选项,最终仅保留None为选中状态 - 点击
All时:清空所有已选中的其他选项,最终仅保留All为选中状态 - 点击普通数值选项时:自动移除当前选中的
All/None,保留其他已选的普通数值,支持多数值同时选中
模板调整
移除原来单个toggle上绑定的click事件,所有选中逻辑统一在group的change回调里处理,避免事件触发顺序错乱导致值异常,修改后模板如下:
<mat-button-toggle-group #group="matButtonToggleGroup" style="margin-left: -100%; margin-right:20px" appearance="legacy" name="fontStyle" aria-label="Font Style" [value]="selectedTime" (change)="onValChange(group.value)" multiple > <mat-button-toggle style="color: black" disabled>Time</mat-button-toggle> <mat-button-toggle *ngFor="let time of getTime()" style="outline: none !important;" [value]="time.timeno" > {{time.timeno}} </mat-button-toggle> </mat-button-toggle-group>
TS侧代码实现
先通过ViewChild拿到toggle组实例,用于手动修正选中状态,适配multiple模式把选中值初始化为数组类型,具体逻辑如下:
import { Component, ViewChild } from '@angular/core'; import { MatButtonToggleGroup } from '@angular/material/button-toggle'; @Component({ // 原有组件元数据保持不变 }) export class YourComponent { // 获取toggle组实例 @ViewChild('group') toggleGroup: MatButtonToggleGroup; // 选中值定义为数组类型,匹配multiple模式要求 selectedTime: (string | number)[] = []; onValChange(currentValue: (string | number)[]) { // 取本次最新点击选中的值 const latestPick = currentValue.at(-1); let finalSelected: (string | number)[] = []; if (latestPick === 'None') { finalSelected = ['None']; } else if (latestPick === 'All') { finalSelected = ['All']; } else { // 选普通值时过滤掉所有特殊选项,保留已选的普通数值 finalSelected = currentValue.filter(item => item !== 'All' && item !== 'None'); } // 同步绑定值 this.selectedTime = finalSelected; // 手动更新组件视图状态,避免多选默认行为导致的选中状态不一致 this.toggleGroup.writeValue(finalSelected); // 这里执行原来changeTimeSelection里的业务逻辑即可,比如根据选中的时间段查询数据 // 可以遍历finalSelected匹配对应的time对象拿begin、end参数 } // 原有getTime()方法保持不变 getTime() { // 原有逻辑 } }
注意点
- 初始需要默认选中All/None的话,直接给
selectedTime赋初始值['All']或['None']即可 - 1、2、3之间的多选交互完全不受影响,符合原生multiple模式的操作习惯
- 不会出现特殊选项和普通值共存、All和None同时选中的异常状态
内容的提问来源于stack exchange,提问作者Matt
相关产品推荐
相关产品推荐

