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

Angular Material 15表格行失焦触发事件的替代实现方案

替代方案解决Angular Material v15表格行失去焦点触发方法的问题

因为<mat-row>本身不支持blur事件,你可以用以下几种可行方案实现需求:

方案1:给行添加tabindex并使用focusout事件

给<mat-row>设置tabindex让它能获取焦点,然后绑定focusout事件,当行失去焦点时触发方法。同时处理点击其他行时的焦点切换:

修改你的表格行代码:

<mat-row 
  *matRowDef="let row; columns: displayedColumns;"
  tabindex="0"
  (focusout)="saveData(row)"
  (click)="$event.target.focus()"
></mat-row>
  • tabindex="0"让行可以通过点击或键盘聚焦
  • (focusout)在元素失去焦点时触发,覆盖点击其他行或表格外区域的场景
  • (click)事件确保点击行时主动获取焦点,保证focusout能正确触发

方案2:监听全局点击事件判断行失去焦点

通过监听document的点击事件,对比点击目标是否属于当前选中的行,触发保存逻辑:

  1. 在组件类中定义变量记录当前选中的行:
currentActiveRow: any;
  1. 给<mat-row>绑定点击事件记录选中行:
<mat-row 
  *matRowDef="let row; columns: displayedColumns;"
  (click)="setActiveRow(row)"
></mat-row>
  1. 在组件中实现逻辑:
setActiveRow(row: any) {
  // 如果之前有选中的行,先执行保存
  if (this.currentActiveRow && this.currentActiveRow !== row) {
    this.saveData(this.currentActiveRow);
  }
  this.currentActiveRow = row;
}

@HostListener('document:click', ['$event'])
onDocumentClick(event: MouseEvent) {
  const target = event.target as HTMLElement;
  // 判断点击的元素是否属于表格行
  const isRowClicked = target.closest('mat-row') !== null;
  if (!isRowClicked && this.currentActiveRow) {
    this.saveData(this.currentActiveRow);
    this.currentActiveRow = null;
  }
}

这个方案不需要行可聚焦,通过全局点击判断是否离开行区域。

方案3:使用Angular CDK的FocusMonitor服务

利用Angular CDK提供的FocusMonitor监听行的焦点变化,适合复杂的焦点管理场景:

  1. 导入依赖:
import { FocusMonitor } from '@angular/cdk/a11y';
import { ElementRef } from '@angular/core';
  1. 在组件中注入服务并监听行元素:
constructor(private focusMonitor: FocusMonitor) {}

ngAfterViewInit() {
  // 获取所有mat-row元素
  const rows = document.querySelectorAll('mat-row');
  rows.forEach(row => {
    const rowElement = row as HTMLElement;
    // 设置tabindex让元素可聚焦
    rowElement.tabIndex = 0;
    // 监听焦点变化
    this.focusMonitor.monitor(rowElement).subscribe(focusOrigin => {
      if (!focusOrigin) {
        // 失去焦点时触发,focusOrigin为null表示失去焦点
        const rowData = JSON.parse(rowElement.dataset['rowData'] || '{}');
        this.saveData(rowData);
      }
    });
  });
}

ngOnDestroy() {
  // 销毁监听,防止内存泄漏
  this.focusMonitor.stopMonitoringAll();
}
  1. 修改模板绑定行数据到dataset:
<mat-row 
  *matRowDef="let row; columns: displayedColumns;"
  [attr.data-row-data]="row | json"
></mat-row>

这个方案更灵活,能处理键盘导航等各种焦点丢失场景。

内容的提问来源于stack exchange,提问作者Darrell

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 19:23:27