如果你是新项目,那么不建议使用
如果你已经使用了,建议替换,如果不方便替换,那么可参考本文来进行一些调整(希望你别看吐了),
整理不易, 如果觉得对你有用 请点赞,让更多人避坑
一堆恶心的属性要配置, 才能勉强使用
const ref = useRef<AgGridReact>(null)
const gridRef = props.gridRef || ref
<AgGridReact
domLayout={'autoHeight'}
suppressPropertyNamesCheck
suppressMoveWhenRowDragging
suppressColumnVirtualisation
rowDragManaged={true}
localeText={localeText}
animateRows={true}
className={` ${
colorScheme === 'dark'
? 'ag-theme-alpine-dark '
: 'ag-theme-alpine'
} ${className}`}
onSortChanged={onSortChanged}
onColumnMoved={onColumnMoved}
ref={gridRef}
rowData={
isPinnedTopTotalRow
? postedData?.filter((item) => !item.total_row)
: postedData
}
pinnedTopRowData={
isPinnedTopTotalRow
? postedData?.filter((item) => item.total_row)
: undefined
}
columnDefs={columnDefs.map((item, index) => ({
...item,
comparator: () => 0,
// pinned 列不会显示图标
...(index === 0 && { rowDrag: true }),
}))}
defaultColDef={defaultColDef}
onFirstDataRendered={(params) => {
if (disableAdjustWidth) {
return
}
params.columnApi.autoSizeAllColumns(false)
}}
loadingOverlayComponent={LoadingOverlayComponent}
noRowsOverlayComponent={() => <>empty</>}
onGridReady={({ columnApi }) => {
// columnApi.setColumnsVisible(hidden, false)
// 这里设置sort的话,会触发sortChange,
// TODO [UI] createTab之后,会导致sort icon 不显示,
onGridReady(true)
}}
preventDefaultOnContextMenu
enableCellTextSelection
{...gridProps}
/>
缺点:
- 自带的tooltip,样式丑陋,而且不会自动换行,导致内容溢出被遮挡,也不会自动调整上下方向,大概率需要自己实现, 实现时最好实现tooltip支持鼠标滑入不消失 github.com/ag-grid/ag-…, 而且显示的字段需要额外指定
tooltipField?: string;
,如果字段是valueGetter渲染的,那么gg吧
cellRender 无法垂直居中
解决办法:
- 无换行列时:
.ag-cell-wrapper:{height:100%}
- 有换行列: 无解
cellRenderer: (params) => {
const row = params.data
return (
<Group spacing={'xs'} align="item-center">
<Checkbox
checked={row.status === 0}
onChange={(event) =>
onStatusChange(row, event.currentTarget.checked)
}
/>
</Group>
)
},
调整行高不生效
文档用法:
.ag-theme-alpine { --ag-grid-size: 3px; --ag-list-item-height: 20px; }
按照文档的用法是不会生效的
解决办法:
.ag-theme-alpine.compact,
.ag-theme-alpine-dark.compact {
--ag-grid-size: 3px;
--ag-font-size: 0.6875rem;
/* --ag-cell-horizontal-padding: 0.875rem; */
--ag-list-item-height: 20px;
}
.ag-theme-alpine.compact .ag-layout-auto-height .ag-center-cols-clipper,
.ag-theme-alpine.compact .ag-layout-auto-height .ag-center-cols-container,
.ag-theme-alpine.compact .ag-layout-print .ag-center-cols-clipper,
.ag-theme-alpine.compact .ag-layout-print .ag-center-cols-container,
.ag-theme-alpine-dark.compact .ag-layout-auto-height .ag-center-cols-clipper,
.ag-theme-alpine-dark.compact .ag-layout-auto-height .ag-center-cols-container,
.ag-theme-alpine-dark.compact .ag-layout-print .ag-center-cols-clipper,
.ag-theme-alpine-dark.compact .ag-layout-print .ag-center-cols-container {
min-height: 3.125rem;
}
- onSort 事件不给出排序的field 和sortDirection, 需要使用 GridRef 去自己捞取数据
const onSortChanged = () => {
const displayColumns = gridRef.current?.columnApi
.getAllDisplayedColumns()
.filter((item) => item.sortIndex != null)
displayColumns?.sort((a, b) => a.sortIndex - b.sortIndex)
const withSortColumns = columnDefs.map((column) => ({
...column,
sortIndex: displayColumns?.find((it) => it.colDef.field === column.field)
?.sortIndex,
sort: displayColumns?.find((it) => it.colDef.field === column.field)
?.sort,
}))
setColumnDefs(withSortColumns)
}
- onMove 事件给出排序的field,和toIndex,然后自己整理出新的数组(合理), 但是本来按住ctrl才支持整体排序,在不按ctrl时多次快速拖拽,也会触发整体排序,而且拿到的数据是错误的
// 只处理了单列拖拽, 整体拖拽得疯狂遍历, 太浪费性能就没搞
const onColumnMoved = useCallback(
(event) => {
if (isEmpty(event.column)) {
return notifications.show({
message: '提示:保存时,无法支持多列排序的顺序!',
color: 'yellow',
})
}
const fromIndex = columnDefs.findIndex(
(column) => column.key === event.column!.colId
)
if (fromIndex === -1) return
const sorted = arrayMoveImmutable(columnDefs, fromIndex, event.toIndex)
setColumnDefs(sorted)
},
[columnDefs, setColumnDefs]
)
- 宽度很死板(最严重), 讲道理,table元素, 使用
white-space
来保证表头和内容全显示是常识,除了长内容需要特殊处理,但是 ag-grid 的css很垃圾 (看过css世界以及dom小测,这点评鉴力还是有的) , 以至于:
列少不会自动撑满宽度,导致右侧有空格; 列多时,表头会显示省略号,需要自己使用 columnApi.autoSizeAllColumns(false)
调整一下, 但是列少时,只想要撑满,你应该使用sizeToFit
,因此, 需要人工判断该调用哪个api, 另外使用api调整好了宽度,当排序图标出现时,又会使表头出现省略号
antd正确: 的宽度由内容撑开
ag-grid 错误: 写死宽度
宽度 demo:
根据列的数量来判断也不对,总之 貌似是个无解的题
类比antd,做的就很好, 列少时,会自动撑满整行,列多时表头不会显示省略号,没有任何负担
另外, 自动调整宽度 + 左侧固定列一起使用时, 会导致可滚动列的宽度很小, 这可能不算ag-grid的bug,但是真的巨特么难用
- 没有任何好看的主题, 需要自己去构建,社区也没有
showLoadingOverlay 不生效
issue: github.com/ag-grid/ag-…
解决办法1(可能解决): noRowsOverlayComponent 做成动态的
useEffect(() => {
loading && gridReady
? gridRef.current?.api?.showLoadingOverlay()
: gridRef.current?.api?.hideOverlay()
})
loadingOverlayComponent={()=> <span>loading</span>}
// noRowsOverlayComponent={()=> <span>empty</span>}
noRowsOverlayComponent={() => (loading ? <span>loading</span> : <span>empty</span>)}
useEffect 里执行ref, 这是react文档推荐的 Best practices for refs的, 我们的用法没错,但是依然可能不显示loading
解决办法2: 去掉useEffect, 直接判断,仍然可能失效 哈哈
```jsx
loading && gridReady
? gridRef.current?.api?.showLoadingOverlay()
: gridRef.current?.api?.hideOverlay()
```
解决办法3: 自己用一个div模拟loading来包装ag-grid,然后禁用他自带的loading, 貌似也不好用,所以放弃了(我尝试过,忘记了)
表头没有水平居中的方法
而在 antd 里 `align:'center'`