Angular中如何检测mat-autocomplete选项是否被选中
判断mat-autocomplete选项选中状态并禁用输入框实现方法
你可以根据业务场景选择以下3种实现方式,不需要额外做复杂的DOM查询:
方式1:使用组件原生选中事件(最推荐,准确率最高)
mat-autocomplete 原生提供optionSelected事件,仅当用户通过点击、回车操作真正选中下拉选项时才会触发,完全不会和用户手动输入的内容混淆,不会出现误判。
- 首先修改HTML模板,给组件绑定选中事件:
<input [matAutocomplete]="auto" matInput formControlName="targetListValue"> <mat-autocomplete #auto="matAutocomplete" [displayWith]="displayFn" (optionSelected)="onOptionSelected($event)" > <mat-option *ngFor="let targetItem of filteredTargetListOptions" [value]="targetItem"> {{targetItem.value}} </mat-option> </mat-autocomplete>
- 在TS文件中编写对应处理逻辑,事件触发就代表已有有效选项被选中,直接执行禁用即可:
onOptionSelected() { // 如需获取选中的具体选项,可通过$event.option.value拿到绑定的targetItem对象 this.form.controls.targetListValue.disable(); }
方式2:校验表单控件值(兼容手动赋值场景)
如果你需要在代码中手动给表单项赋值、同时也要触发禁用逻辑,可以直接校验表单控件的当前值是否属于有效选项列表,不需要依赖组件事件:
// 页面初始化时订阅控件值变化,实时监听选中状态 ngOnInit() { this.form.controls.targetListValue.valueChanges.subscribe(currentValue => { // 校验逻辑:值存在,且能在选项列表中找到匹配项,才算有效选中 const hasSelected = !!currentValue && this.filteredTargetListOptions.some(item => { // 比对逻辑根据你的数据结构调整,比如比对唯一id、比对value字段都可以 return item.value === currentValue.value; }); if (hasSelected) { // 加emitEvent:false避免禁用操作触发额外的值变化回调,防止死循环 this.form.controls.targetListValue.disable({ emitEvent: false }); } }) } // 你原有逻辑中的ifSelectedItem方法可按如下方式实现 ifSelectedItem() { const currentValue = this.form.controls.targetListValue.value; const hasSelected = !!currentValue && this.filteredTargetListOptions.some(option => option.value === currentValue.value); if (hasSelected) { this.form.controls.targetListValue.disable(); } }
注意:不要直接通过「表单控件有值」判断选中状态,用户手动输入内容时控件也会存值,但此时并没有选中下拉选项,必须校验值匹配选项列表才算有效选中。
方式3:通过MatAutocomplete实例直接获取选中状态
你已经在模板中用模板变量#auto获取了MatAutocomplete实例,可以通过ViewChild在TS中拿到实例,直接遍历所有选项判断选中状态,适合需要直接操作组件实例的场景:
// 拿取模板中的mat-autocomplete实例 @ViewChild('auto') autoRef: MatAutocomplete; ifSelectedItem() { // 实例的options属性是所有mat-option的集合,遍历判断selected属性即可 const hasSelected = this.autoRef.options.some(option => option.selected); if (hasSelected) { this.form.controls.targetListValue.disable(); } }
注意事项
- 如果选项绑定的value是字符串、数字这类基本类型,判断选中时直接比对值即可,不需要遍历对象属性
- 调用
disable()方法时传入{ emitEvent: false }可以避免触发不必要的值变化回调,防止逻辑死循环 - 优先使用
optionSelected事件的实现方式,不需要每次值变化都遍历选项列表,性能更好
内容的提问来源于stack exchange,提问作者Dmitry Chernyak
相关产品推荐
相关产品推荐

