AGGrid自定义cellRenderer下tooltipShowMode不生效如何处理?
摘要
AG Grid 中设置tooltipShowMode: 'whenTruncated'后,普通单元格可以只在文本被截断时显示 tooltip;但如果列使用cellRendererSelector或自定义 cell renderer,tooltip 逻辑会换到 renderer 内部。本文基于 AG Grid 官方 issue 回复,整理setTooltip(value, shouldDisplayTooltip)的使用方式。
问题背景
一个常见需求是:表格里有一列描述文本,内容很长时用省略号显示;鼠标悬停时,只在文本被截断的情况下显示完整 tooltip。普通列上可以这样配置:
constgridOptions={tooltipShowMode:"whenTruncated",columnDefs:[{field:"description",tooltipField:"description"}]};但当这一列改成自定义 renderer,尤其是通过cellRendererSelector动态选择 renderer 时,开发者可能会发现:即使内容没有截断,tooltip 仍然显示;或者tooltipShowMode像没有生效一样。
AG Grid issue #13779 讨论的就是这个现象。官方维护者给出的结论是:这不是单纯的回归 bug。列级别的tooltipShowMode: 'whenTruncated'是基于 Grid 自己渲染的单元格文本判断截断状态;当单元格内容由自定义 renderer 接管后,tooltip 应该由 renderer 通过setTooltip(value, shouldDisplayTooltip)自己注册。
官方回复要点
AG Grid 维护者说明:
tooltipShowMode: 'whenTruncated'依赖 Grid 自身的 cell text。- 自定义 cell renderer,包括由
cellRendererSelector选出的 renderer,需要在 renderer 内部调用setTooltip。 setTooltip的第二个参数shouldDisplayTooltip是条件函数,适合放“当前内容是否被截断”的判断。- 如果使用
enableBrowserTooltips,该条件回调不适用,因为浏览器原生 tooltip 不由 Grid 控制。
所以,正确思路不是继续在 column definition 上堆 tooltip 配置,而是让自定义 renderer 对自己渲染的 DOM 负责。
实现步骤
第一步,给自定义 renderer 的文本元素保留可测量的 DOM 引用。下面示例以 React cell renderer 为例:
import { useLayoutEffect, useRef } from "react"; import type { CustomCellRendererProps } from "ag-grid-react"; type RowData = { id: number; description: string; kind: "short" | "long"; }; export function DescriptionRenderer( props: CustomCellRendererProps<RowData, string> ) { const textRef = useRef<HTMLSpanElement | null>(null); const tooltipValue = String(props.value ?? ""); const { setTooltip } = props; useLayoutEffect(() => { setTooltip(tooltipValue, () => { const el = textRef.current; return !!el && el.scrollWidth > el.clientWidth; }); }, [setTooltip, tooltipValue]); return ( <span ref={textRef} className="cell-ellipsis"> {tooltipValue} </span> ); }对应样式要真正造成截断,否则scrollWidth > clientWidth永远不会成立:
.cell-ellipsis{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}第二步,在列定义中使用该 renderer。即便全局仍保留tooltipShowMode: 'whenTruncated',自定义 renderer 这列也要靠setTooltip自己判断。
constcolumnDefs=[{field:"id",width:100},{field:"description",cellRendererSelector:params=>{return{component:DescriptionRenderer,params:{emphasis:params.data?.kind==="long"}};}}];第三步,确认没有启用浏览器原生 tooltip:
constgridOptions={enableBrowserTooltips:false,tooltipShowMode:"whenTruncated",columnDefs};enableBrowserTooltips: true时,tooltip 行为交给浏览器,AG Grid 文档也说明setTooltip的条件回调不适用。想要“只在截断时显示”,应使用 Grid tooltip 机制。
排查清单
- 确认这一列是否使用了
cellRenderer或cellRendererSelector。如果是,优先检查 renderer 内部是否调用了setTooltip。 - 检查用于测量的元素是否就是实际被截断的元素,而不是外层容器。
- 检查 CSS 是否同时具备
overflow: hidden、text-overflow: ellipsis和white-space: nowrap。 - 确认
enableBrowserTooltips没有被设为true。 - 如果单元格内容会异步变化,确保变化后重新调用
setTooltip或触发 renderer 刷新。 - 如果 renderer 内有图标、按钮、标签等复杂结构,不要只根据字符串长度判断,要测量真实 DOM 宽度。
版本与注意事项
原 issue 的复现场景是 AG Grid35.3.0和 React。本文示例按当前 AG Grid React 文档中的CustomCellRendererProps与setTooltip机制整理。
示例未在当前工作区绑定对应版本的 AG Grid 依赖进行编译;不同主版本的类型导出位置、renderer props 命名可能略有差异,请以项目所用版本的 API 文档和 IntelliSense 为准。
此外,tooltipShowMode: 'whenTruncated'并不是“所有 tooltip 的全局截断判断器”。它适合 Grid 自己渲染文本的场景;当你接管单元格 DOM 后,就需要接管 tooltip 的显示条件。
总结
这个问题的关键不在于tooltipShowMode写错了,而在于单元格的渲染职责已经从 Grid 转移到了自定义 renderer。普通列可以让 Grid 判断文本是否截断;自定义 renderer 则应使用setTooltip注册 tooltip,并通过shouldDisplayTooltip测量自己的 DOM 是否溢出。这样才能让“只在截断时显示 tooltip”的规则和真实 UI 保持一致。
内容来源说明
- 官方问答来源:AG Grid GitHub issue #13779,维护者于 2026-06-19 给出解释并关闭 issue。
- API 核查来源:
- https://github.com/ag-grid/ag-grid/issues/13779
- https://www.ag-grid.com/react-data-grid/component-cell-renderer/#dynamic-tooltips
- https://www.ag-grid.com/react-data-grid/tooltips/
