Angular Material:选择自动完成组件的mat-option时如何避免触发blur事件
Angular Material:选择自动完成组件的mat-option时如何避免触发blur事件
我太懂你这种困扰了——在Angular 16及更高版本里,原来靠relatedTarget判断是否点击mat-option的老办法彻底失效了,毕竟Material组件现在会让这个属性返回null。别担心,我给你两个亲测有效的解决方案,完美解决选择选项时误触发blur事件的问题:
方案一:利用optionSelected事件结合标志位
这个方法的核心思路是:当用户选择下拉选项时,先通过optionSelected事件标记“正在选择选项”,让后续的blur事件检测到这个标记后跳过执行逻辑,最后再重置标记不影响后续操作。
组件类代码
import { Component } from '@angular/core'; import { FormControl } from '@angular/forms'; @Component({ selector: 'select-overview-example', templateUrl: 'select-overview-example.html', }) export class SelectOverviewExample { myControl = new FormControl(''); options: string[] = ['One', 'Two', 'Three']; // 定义标志位,标记是否正在选择选项 isOptionSelected = false; // 选项被选中时触发的方法 onOptionSelected() { this.isOptionSelected = true; // 用setTimeout把重置操作放到微任务队列之后,确保blur事件能先检测到标记 setTimeout(() => { this.isOptionSelected = false; }, 0); } // 输入框失焦时触发的方法 onBlur() { // 如果是选择选项导致的失焦,直接返回不执行后续逻辑 if (this.isOptionSelected) { return; } // 这里写你原本blur事件要执行的逻辑,比如示例里的console.log(1) console.log(1); } // 选项选中后的逻辑,比如示例里的console.log(2) onOptionSelectAction(option: string) { console.log(2); // 其他后续操作... } }
模板代码
<input type="text" matInput [formControl]="myControl" [matAutocomplete]="auto" (blur)="onBlur()"> <mat-autocomplete #auto="matAutocomplete" (optionSelected)="onOptionSelected(); onOptionSelectAction($event.option.value)"> <mat-option *ngFor="let option of options" [value]="option"> {{option}} </mat-option> </mat-autocomplete>
方案二:监听mat-option的mousedown事件
另一种思路是利用事件触发顺序:mousedown事件会在blur事件之前触发,所以我们可以在点击选项时标记状态,让blur事件根据这个状态决定是否执行。
组件类代码
import { Component } from '@angular/core'; import { FormControl } from '@angular/forms'; @Component({ selector: 'select-overview-example', templateUrl: 'select-overview-example.html', }) export class SelectOverviewExample { myControl = new FormControl(''); options: string[] = ['One', 'Two', 'Three']; // 标记是否点击了选项 isOptionClicked = false; // 点击选项时触发mousedown事件 onOptionMouseDown() { this.isOptionClicked = true; } onBlur() { // 如果是点击选项导致的失焦,重置标记并返回 if (this.isOptionClicked) { this.isOptionClicked = false; return; } // 执行原本的blur逻辑 console.log(1); } onOptionSelectAction(option: string) { console.log(2); // 其他后续操作... } }
模板代码
<input type="text" matInput [formControl]="myControl" [matAutocomplete]="auto" (blur)="onBlur()"> <mat-autocomplete #auto="matAutocomplete" (optionSelected)="onOptionSelectAction($event.option.value)"> <mat-option *ngFor="let option of options" [value]="option" (mousedown)="onOptionMouseDown()"> {{option}} </mat-option> </mat-autocomplete>
这两个方案都能实现你的预期:当用户选择mat-option时,只会执行选项选中的逻辑(打印2),不会触发blur的逻辑(打印1);而当用户手动输入值后失焦时,会正常执行blur的逻辑。
备注:内容来源于stack exchange,提问作者avishekdr
相关产品推荐
相关产品推荐

