Dash Ag-Grid表格文本截断展开功能实现技术问询
解决Dash Ag-Grid长文本单元格截断+展开/收起功能问题
你的自定义单元格渲染器未生效,大概率是JS代码里的HTML转义错误、事件绑定逻辑或AgGrid配置配合问题。以下是修正后的完整实现,直接可用:
1. 修正后的自定义单元格渲染器JS代码
这段代码需通过Dash的html.Script组件注入页面,修复了HTML转义问题,优化了样式和事件逻辑:
window.dashAgGridComponentFunctions = window.dashAgGridComponentFunctions || {}; class TruncatedTextCell { init(params) { this.params = params; this.eGui = document.createElement('div'); this.eGui.className = 'truncated-cell'; // 支持从列定义传入maxLength,默认100 this.maxLength = params.colDef.maxLength || 100; this.isExpanded = false; this.render(); } getGui() { return this.eGui; } render() { const text = this.params?.value ? String(this.params.value) : ''; const truncatedText = text.length > this.maxLength ? text.substring(0, this.maxLength) + '...' : text; if (this.isExpanded) { this.eGui.innerHTML = ` <div style="position: relative; padding: 8px;"> <div style="white-space: pre-wrap; word-break: break-word;">${this.escapeHtml(text)}</div> <button style="position: absolute; top: 8px; right: 8px; padding: 4px 8px; font-size: 12px; background-color: #3b82f6; color: white; border-radius: 4px; border: none; cursor: pointer;" class="show-less-btn"> Show Less </button> </div> `; const showLessBtn = this.eGui.querySelector('.show-less-btn'); showLessBtn.addEventListener('click', (e) => { e.stopPropagation(); this.isExpanded = false; this.render(); // 通知AgGrid重新计算行高 this.params.api.onRowHeightChanged(); }); } else { this.eGui.innerHTML = ` <div style="display: flex; align-items: center; gap: 8px; padding: 4px; min-height: 28px;"> <span style="overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex: 1;">${this.escapeHtml(truncatedText)}</span> ${text.length > this.maxLength ? ` <button style="padding: 4px 8px; font-size: 12px; background-color: #3b82f6; color: white; border-radius: 4px; border: none; cursor: pointer; flex-shrink: 0;" class="expand-btn"> ... </button> ` : ''} </div> `; const expandBtn = this.eGui.querySelector('.expand-btn'); if (expandBtn) { expandBtn.addEventListener('click', (e) => { e.stopPropagation(); this.isExpanded = true; this.render(); // 通知AgGrid重新计算行高 this.params.api.onRowHeightChanged(); }); } } } escapeHtml(unsafe) { return unsafe .replace(/&/g, "&") .replace(/</g, "<") .replace(/>/g, ">") .replace(/"/g, """) .replace(/'/g, "'"); } refresh(params) { this.params = params; this.render(); return true; } destroy() {} } window.dashAgGridComponentFunctions.TruncatedTextCell = (params) => { const component = new TruncatedTextCell(); component.init(params); return component; };
2. Python Dash应用代码
需将JS代码通过html.Script引入,同时配置AgGrid的autoHeight和自定义列参数:
from dash import Dash, html import dash_ag_grid as dag # 模拟测试数据 data = [ { "Patent ID": "US1234567", "Title": "Test Patent", "Abstract": "Short abstract", "Summarised Description": "这是一段非常长的文本,用来测试Dash Ag-Grid的单元格截断功能。当文本长度超过设定的最大字符数时,应该显示截断后的内容和展开按钮,点击按钮可以查看完整文本,再次点击可以收起。" * 5, "Family": "US", "Country Code": "US", "Organization": "Test Org", "DA": "Yes", "Publication Date": "2023-01-01", "Priority Date": "2022-01-01" } ] app = Dash(__name__) columnDefs = [ {'field': 'Patent ID'}, {'field': 'Title'}, {'field': 'Abstract'}, { "field": "Summarised Description", "cellRenderer": "TruncatedTextCell", "width": 400, "autoHeight": True, # 自定义最大截断长度,可选,默认100 "maxLength": 100 }, {'field': 'Family'}, {'field': 'Country Code'}, {'field': 'Organization'}, {'field': 'DA'}, {'field': 'Publication Date'}, {'field': 'Priority Date'} ] app.layout = html.Div([ dag.AgGrid( id='patent-grid', rowData=data, columnDefs=columnDefs, defaultColDef={'resizable': True} ), # 注入自定义单元格渲染器JS代码(若JS存为文件则用open读取,也可直接写children) html.Script(children=open('truncated_cell_renderer.js').read()) ]) if __name__ == '__main__': app.run_server(debug=True)
关键改动说明
- 修复JS代码中HTML字符串的转义错误,确保结构正确解析
- 支持从列定义传入
maxLength参数,灵活控制不同列的截断长度 - 添加
this.params.api.onRowHeightChanged()调用,确保展开/收起时AgGrid自动调整行高 - 优化CSS样式,让截断文本布局和按钮位置更合理
- 保留HTML转义函数,防止XSS攻击
内容的提问来源于stack exchange,提问作者Paresh Pandya
相关产品推荐
相关产品推荐

