首页 > 解决方案 > 修改在 ag-grid 上排序的内容

问题描述

TL;DR:如何在运行时更改要排序的字段(假设:单元格使用多个值)

目前我正在Angular中创建一个ag-grid,其中包含多个数据点用于给定单元格(valueGetter)的列。鉴于此,我希望允许用户能够根据他们想要的任何字段进行排序。

目前,我能够有一个解决方法,我覆盖列菜单以显示给定列的特定字段(它有改进的余地,以使所有列更通用,但这是一个不同的主题)。我为此提供了一个函数,它将更新列定义,替换原来的比较器,并刷新列定义。

这(更新列定义)并不理想,因为它会关闭当前在侧栏中打开的过滤器。所以我的问题是:有没有更好的方法来改变你在运行时为给定列排序的内容(不更新列定义)?非常利基的用例,但这是我上面提到的相关代码:

覆盖菜单项:

 getMainMenuItems(params) {
    const defaultMenuItems = [];
    switch(params.column.getId()) {
      case 'product':
        defaultMenuItems.push(
          {
            name: 'Sort By Customer',
            action: () => this.updateComparatorOnColDef('customer', 'issuer'),
            checked: params.column.userProvidedColDef.sortBy === 'customer'
          },
          {
            name: 'Sort By Product Type',
            action: () => this.updateComparatorOnColDef('product', 'productType'),
            checked: params.column.userProvidedColDef.sortBy === 'productType'
          },
          {
            name: 'Sort By ProductID',
            action: () => this.updateComparatorOnColDef('product', 'productId'),
            checked: params.column.userProvidedColDef.sortBy === 'productId'
          },
        );
        return defaultMenuItems;
      default:
        return params.defaultItems;
    }
  }

更新列定义

 updateComparatorOnColDef(colId: string, dataProperty: string) {
const newColDefs = _.cloneDeep(this.columnDefs);
const colDef = newColDefs.find(x => x.colId === colId);
if(colDef?.comparator) {
  colDef.comparator = (valueA, valueB, nodeA, nodeB, isInverted) => {
    if(typeof valueB[dataProperty] === 'string' && typeof valueA[dataProperty] === 'string') {
      return ((valueA[dataProperty].toLowerCase()) > (valueB[dataProperty].toLowerCase())) ? 1 : -1;
    } else {
      return (valueA[dataProperty] > valueB[dataProperty]) ? 1 : -1;
    }
  };
  colDef.sortBy = dataProperty; // used to display the check where appropriate on the column menu
  this.gridApi.setColumnDefs(newColDefs);
}

}

编辑:侧边栏重新打开在列定义更新后之前打开的过滤器:

updateComparatorOnColDef(colId: string, dataProperty: string) {
// todo: pass in config param to tell how to compare or do logic to infer types (for misc. values, like % ranges(ex: 12% - 20%))
const openFilters = [];
const filtersToolPanel = this.gridApi.getToolPanelInstance('filters');
for(const filter of filtersToolPanel.filtersToolPanelListPanel.filterGroupComps) {
  if(filter.isExpanded()) {
    openFilters.push(filter.getFilterGroupId());
  }
}
const newColDefs = _.cloneDeep(this.columnDefs);
const colDef = newColDefs.find(x => x.colId === colId);
if(colDef?.comparator) {
  colDef.comparator = this.generateComparator(dataProperty);
  colDef.sortBy = dataProperty;

  this.gridApi.setColumnDefs(newColDefs);
  this.gridApi.getToolPanelInstance('filters').expandFilters(openFilters);
}

}

标签: angularag-gridag-grid-angular

解决方案


如果我正确理解了您的问题,那么您将valueGetter更改列的值,并且这些值应该以不同的方式排序。我建议在其中实现一个comparator并添加逻辑,以根据节点中的值进行排序。请参阅有关自定义排序的文档。


推荐阅读