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

Angular Mat Table添加mat-sort-header后resizeColumn列宽调整失效如何解决

问题根因

冲突来源于两点:

  • mat-sort-header 会自动拦截表头的所有鼠标事件,你插入的拖拽触发元素的mousedown事件被冒泡拦截后无法触发拖拽逻辑
  • mat-header-cell 默认设置了flex: 1 1 auto属性,作为flex容器的子项,直接设置width属性不会生效,flex布局会自动重算宽度

修复方案

1. 修改自定义resizeColumn指令代码

核心修改两处逻辑:

  • 拖拽触发时阻止事件冒泡,避免触发排序逻辑
  • 设置宽度时同时覆盖flex属性,强制固定宽度生效

修改后的完整指令代码如下:

import { Directive,OnInit, Renderer2, Input, ElementRef} from '@angular/core';

@Directive({
  selector: '[resizeColumn]'
})
export class ResizecolDirective implements OnInit {

  @Input("resizeColumn") resizable!:boolean;
  private startX!:number;
  private startWidth!:number;
  private column!: HTMLElement;
  private table!: HTMLElement;
  private pressed!: boolean;

  constructor(private renderer: Renderer2, private el: ElementRef) { 
    this.column = this.el.nativeElement;
  }
  ngOnInit(){
    if (this.resizable) {
      const row = this.renderer.parentNode(this.column);
      const thead = this.renderer.parentNode(row);
      this.table = this.renderer.parentNode(thead);
      const resizer = this.renderer.createElement("span");
      this.renderer.addClass(resizer, "resize-holder");
      this.renderer.appendChild(this.column, resizer);
      this.renderer.listen(resizer, "mousedown", this.onMouseDown);
      this.renderer.listen(this.table, "mousemove", this.onMouseMove);
      this.renderer.listen("document", "mouseup", this.onMouseUp);
    }
  }
  onMouseDown = (event: MouseEvent) => {
    // 阻止事件冒泡和默认行为,避免触发排序
    event.stopPropagation();
    event.preventDefault();
    this.pressed = true;
    this.startX = event.pageX;
    this.startWidth = this.column.offsetWidth;
  };

  onMouseMove = (event: MouseEvent) => {
    const offset = 30;
    if (this.pressed && event.buttons) {
      this.renderer.addClass(this.table, "resizing");
      let width =this.startWidth + (event.pageX - this.startX - offset);
      // 同时覆盖flex和宽度相关属性,强制固定宽度生效
      this.renderer.setStyle(this.column, "flex", `0 0 ${width}px`);
      this.renderer.setStyle(this.column, "width", `${width}px`);
      this.renderer.setStyle(this.column, "max-width", `${width}px`);
    }
  };

  onMouseUp = (event: MouseEvent) => {
    if (this.pressed) {
      this.pressed = false;
      this.renderer.removeClass(this.table, "resizing");
    }
  };
}

2. 添加全局样式保证拖拽触发区正常显示

在项目的全局样式文件(比如styles.scss)中添加以下样式:

.resize-holder {
  position: absolute;
  top: 0;
  right: 0;
  width: 12px;
  height: 100%;
  cursor: col-resize;
  z-index: 999;
  background: transparent;
}
th.mat-header-cell {
  position: relative;
  overflow: visible;
}
table.resizing * {
  user-select: none !important;
}

3. 原有模板无需修改

你的表格代码可以保留mat-sort-header属性,不需要做额外调整,排序和列宽调整功能可以同时生效。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 08:24:09