当列虚拟化开启时,如何自动调整ag-grid中所有列的大小?

问题描述 投票:0回答:1

根据ag-grid文档(https://www.ag-grid.com/javascript-data-grid/column-sizing/

“选择权在您,无论您想要列虚拟化工作还是使用屏幕外列自动调整大小工作”

这意味着如果您有许多列不在屏幕上,它们实际上并不存在,因此不会自动调整大小。

有什么方法可以绕过库中的内置限制,以便我可以利用这两个功能?

ag-grid ag-grid-angular ag-grid-react ag-grid-vue
1个回答
0
投票

我编写了一个方法,它获取每个虚拟列并将其移至屏幕外,自动调整大小,然后将其移回原始位置。此后 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
是一个布尔值,指示列是显示还是隐藏。

这是我能想到的解决库内置限制的最快解决方案。另一个解决方案是以编程方式滚动网格,同时网格被我的加载元素覆盖,但这速度较慢。

© www.soinside.com 2019 - 2024. All rights reserved.