【问题标题】:Ag-Grid: How to save and reload column orderAg-Grid:如何保存和重新加载列顺序
【发布时间】:2018-12-31 11:07:17
【问题描述】:

使用 Ag-Grid,用户可以拖动列以按照他们喜欢的方式对其进行排序。我需要允许用户保存他们的列顺序(到 SQL 后端),以便它成为他们的默认列顺序。我试图得到这样的列名:

var cols = schedGridOptions.columnApi.getAllColumns();
for (col in cols) {
    var colDef = col.getColDef();
    console.log(colDef.headerName);
}

这是我找到的用于设置标题名称的示例,因此我尝试对其进行调整以获取标题名称。但我得到这个错误:

JavaScript 运行时错误:对象不支持属性或方法 'getColDef'

也许我没有正确执行此操作?我对使用 Ag-Grid 还很陌生。寻找建议。

【问题讨论】:

    标签: javascript ag-grid


    【解决方案1】:

    您正在寻找 setColumnState() 和 getColumnState()。请参阅https://www.ag-grid.com/javascript-grid-column-api/ 上的文档

    在您的网格选项中,为 gridReady 和 columnMoved 设置事件处理程序。 https://www.ag-grid.com/javascript-grid-events/

    类似:

    gridOptions = {
       rowData: myRowDataSource,
       columnDefs: myColumns,
       onGridReady: onGridReady,
       onColumnMoved: onColumnMoved,
    }
    

    在列移动事件上,保存 columnState。这是一个保存到本地存储的示例。更改它以保存到您的数据库。

    onColumnMoved(params) {
      var columnState = JSON.stringify(params.columnApi.getColumnState());
      localStorage.setItem('myColumnState', columnState);
    }
    

    在网格就绪事件中,获取并恢复网格状态。同样,将其更改为从您的数据库中提取。

    onGridReady(params) {
        var columnState = JSON.parse(localStorage.getItem('myColumnState'));
        if (columnState) {
          params.columnApi.setColumnState(columnState);
        }
    }
    

    【讨论】:

    • 如果你刚刚登陆这里只是一个提示:由于版本 24 setColumnState 已被弃用,你应该使用 columnApi.applyColumnsState({ state: savedState });见ag-grid.com/javascript-grid-column-state
    • @Sebastian 不适用于列顺序
    【解决方案2】:

    onColumnMoved 将在每次列移动但拖动没有停止时触发。

    使用onColumnMoved 根本没有性能。

    如果你关心性能,你应该使用onDragStopped

    gridOptions.onDragStopped = function (params) {
      const colIds = params.columnApi.getAllDisplayedColumns().map(col => col.colId)
      console.log(colIds) // all visible colIds with the visible order
    }
    

    【讨论】:

    • 非常好的技巧!当您将列拖过表格时,看到商店被反复修改,这有点令人沮丧。
    • 是的,但是这种方法的问题是,如果用户使用上下文菜单重置网格,您需要捕获 columnMoved 以获得通知。这不会导致拖动事件。我认为获取 onColumnMoved 并对其进行去抖动更有意义。
    【解决方案3】:

    我的回答是对@roli 的回答的一个小改进。只有在操作后更改了列顺序时才会触发该事件。如果用户拖动并决定停止并在与以前相同的索引处放下列,则不会触发该事件。

    下面的代码是react中的实现。这个想法很简单:在拖动开始时将列顺序存储为 colId 列表,并将其与拖动停止时的最终列顺序进行比较。只有当两个订单之间存在不同时才会触发该事件。

    function useDragColumnChange(cb: (e: DragStoppedEvent) => void) {
      const columnOrderRef = React.useRef<string[]>([])
      const onDragStarted = (e: DragStartedEvent) => {
        columnOrderRef.current = e.columnApi.getColumnState().map(c => c.colId);
      }
      const onDragStopped = (e: DragStoppedEvent) => {
        const newColumnOrder = e.columnApi.getColumnState().map(c => c.colId);
        const sameOrder = columnOrderRef.current.every(
          (c, i) => c === newColumnOrder[i]
        );
    
        if (!sameOrder) {
          cb(e);
        }
      }
    
      return { onDragStarted, onDragStopped };
    }
    

    用法

    // in render()
    
    const { onDragStarted, onDragStopped } = useDragColumnChange(e => console.log('Saving new column order!'))
    
    return (
      <AgGridReact
        ...
        onDragStarted={onDragStarted}
        onDragStopped={onDragStopped}
      />
    );
    

    现场演示

    【讨论】:

    • 这很好,我一直在使用,直到我意识到如果用户重置他们的网格,它不会捕获列移动(并且没有调用您也绑定到网格的其他事件处理程序 -例如,如果您使用排序重置,则 onSortChanged 会触发)。因此,如果重置只是触发列顺序重置,那么不幸的是,此方法不起作用。如上所述,我现在只需将处理程序去抖动 500 毫秒并以简单的方式进行。
    猜你喜欢
    • 2020-09-02
    • 2021-07-19
    • 2016-02-02
    • 2016-06-05
    • 2021-02-03
    • 2016-03-13
    • 2017-07-03
    • 2021-11-08
    • 1970-01-01
    相关资源
    最近更新 更多