You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.13 19:34:31