根据ag-grid文档(https://www.ag-grid.com/javascript-data-grid/column-sizing/)
“选择权在您,无论您想要列虚拟化工作还是使用屏幕外列自动调整大小工作”
这意味着如果您有许多列不在屏幕上,它们实际上并不存在,因此不会自动调整大小。
有什么方法可以绕过库中的内置限制,以便我可以利用这两个功能?
我编写了一个方法,它获取每个虚拟列并将其移至屏幕外,自动调整大小,然后将其移回原始位置。此后 ag-grid 会记住它的大小。
根据该列是在当前可见列所在位置的左侧还是右侧,它将分别向左或向右移动和调整大小。这样网格就不会跳来跳去,而用户却一无所知。因此,如果显示隐藏列,但位于虚拟化位置,因此需要自动调整大小,也可以使用此方法。
对于大约 30 列,这大约需要 1 秒才能完成。我用另一个大型加载元素覆盖网格,该元素具有这些较大网格的绝对位置,以便用户无法滚动并干扰该过程。我没有展示如何在此解决方案中做到这一点,但这相当简单。
sizeShownColumns(colIds: string[], columnApi: ColumnApi) {
const allCols = columnApi.getAllGridColumns();
const virtualCols = columnApi.getAllDisplayedVirtualColumns().filter(x => { return !x.isPinnedLeft() });
const leftVirtualIndex = allCols.findIndex(c => c.getColId() == virtualCols[0].getColId());
const rightVirtualIndex = allCols.findIndex(c => c.getColId() == virtualCols[virtualCols.length - 1].getColId());
const leftColumns: { col: Column, originalIndex: number }[] = [];
const rightColumns: { col: Column, originalIndex: number }[] = [];
const visibleColumns: Column[] = [];
colIds.forEach(
(id) => {
const originalIndex = allCols.findIndex((c) => c.getId() == id);
if (originalIndex < leftVirtualIndex) {
leftColumns.push({ col: allCols[originalIndex], originalIndex });
} else if (originalIndex > rightVirtualIndex) {
rightColumns.push({ col: allCols[originalIndex], originalIndex });
} else {
visibleColumns.push(allCols[originalIndex]);
}
});
leftColumns.forEach(rc => {
columnApi.moveColumn(rc.col, leftVirtualIndex);
columnApi.autoSizeColumn(rc.col.getColId(), true);
columnApi.moveColumn(rc.col, rc.originalIndex);
});
rightColumns.forEach(rc => {
columnApi.moveColumn(rc.col, rightVirtualIndex);
columnApi.autoSizeColumn(rc.col.getColId(), true);
columnApi.moveColumn(rc.col, rc.originalIndex);
});
visibleColumns.forEach(rc => {
columnApi.autoSizeColumn(rc.getColId(), true);
});
}
要在虚拟化的列上调用它,可以像这样完成:
onFirstDataRendered() {
const unhiddenCols = this.columnApi.getAllGridColumns().filter(x => { return x.isVisible() && !x.isPinned(); }).map(x => x.getColId());
const displayedColumns = this.columnApi.getAllDisplayedVirtualColumns().filter(x => { return x.isVisible() && !x.isPinned(); }).map(x => x.getColId());
const offScreenCols = unhiddenCols.filter(x => !displayedColumns.includes(x));
this.columnSizeService.sizeShownColumns(offScreenCols, this.columnApi);
this.finishedLoading = true;
}
同样,如果您刚刚显示了一些隐藏的列,您可以执行以下操作:
params.columnApi.setColumnsVisible(colIds, show);
if (show) {
this.columnSizeService.sizeShownColumns(colIds, params.columnApi);
}
其中
show
是一个布尔值,指示列是显示还是隐藏。
这是我能想到的解决库内置限制的最快解决方案。另一个解决方案是以编程方式滚动网格,同时网格被我的加载元素覆盖,但这速度较慢。