在 Ag-Grid 中切换浮动过滤器?

Toggle floating filter in Ag-Grid?

我正在尝试通过单击开关或按钮来确定浮动过滤器的显示。看起来很简单。我应该能够在 true 和 false 之间切换,将该值提供给网格选项中的浮动过滤器,然后刷新 header 对吗?不幸的是,网格似乎总是落后一步。当我第一次点击时,没有任何反应。当我将开关切换回 false 时,浮动过滤器就会出现。浮动过滤器将继续出现(当开关为 false 时)并消失(当开关为 true 时)。为了让事情变得更奇怪,如果我切换浮动过滤器开关几次,然后尝试切换 rowGroupPanelShow(我也试图切换),它将触发浮动过滤器切换到它以前不是的任何值。但只有一次。

我已经尝试了一些变体。我试过开关和按钮。我试过观察者并编写自己的函数来切换真假。我试过在与切换相同的函数中调用 this.gridApi.refreshHeader() 并从它自己的函数中调用它。我试过调用 this.columnApi.resetColumnState() (用于重置分组)。所有控制台都正确记录,但网格似乎总是落后一步。

这是我从 ag-grid 的网站上获取并修改以演示行为的一个 link 的一个 plunker:https://plnkr.co/edit/Me51NOVOCbmvFxx95WpP?p=preview

这是开关和网格:

<v-layout row wrap justify-center>
  <v-flex xs6 sm2 md2>
    <v-switch
      class="switch"
      color="blue"
      id="filterSwitch"
      label="Floating Filter"
      v-model="filterSwitch"
    ></v-switch>
  </v-flex>
  <v-flex xs6 sm2 md2>
    <v-switch
      class="switch"
      color="blue"
      id="groupSwitch"
      label="Row Grouping Panel"
      v-model="groupSwitch"
    ></v-switch>
  </v-flex>
</v-layout>
<div class="buys">
  <ag-grid-vue
  id="personTableAgGridTest"
  style="width: 100%; height: 65vh;"
  class="ag-theme-balham"
  :columnDefs="columnDefs"
  :rowData="rowData"
  :cacheBlockSize="cacheBlockSize"
  :rowModelType="rowModelType"
  :enableColResize="true"
  :enableFilter="true"
  :enableSorting="true"
  :rowSelection="rowSelection"
  :animateRows="true"
  :floatingFilter="floatingFilter"
  :maxConcurrentDatasourceRequests="maxConcurrentDatasourceRequests"
  :defaultColDef="defaultColDef"
  :columnTypes="columnTypes"
  :sideBar="sideBar"
  :rowGroupPanelShow="rowGroupPanelShow"
  :gridReady="onGridReady"
  >

  </ag-grid-vue>

这里是相关的绑定数据

export default {
  data() {
    return {
      columnDefs: null,
      rowData: null,
      cacheBlockSize: 250,
      rowSelection: 'multiple',
      maxBlocksInCache: 5,
      gridApi: null,
      columnApi: null,
      rowGroupPanelShow: 'always',
      floatingFilter: false,
      filterSwitch: false,
      groupSwitch: false,
      rowModelType: 'serverSide',
      maxConcurrentDatasourceRequests: 1,

这是functions/watchers

    resetColumns () {
      this.columnApi.resetColumnState()
    },
    refreshHeader2 () {
      console.log('in refresh header', this.floatingFilter)
      this.gridApi.refreshHeader()
      // this.resetColumns()
    }
 },
  watch: {
    filterSwitch (val) {
      console.log('val', val, this.floatingFilter)
      this.floatingFilter = !this.floatingFilter
      this.refreshHeader2()
    },

预期:浮动过滤器是否显示应由开关切换。将开关的值传递给网格,然后刷新 header 应该可以完成此操作。

实际:网格似乎落后了一步(当开关为 false 时显示浮动过滤器)。

在我的评论中,我建议用 setTimeout(..., 0):

修复它

https://plnkr.co/edit/9NAfPeEu8GgJw7okqz77?p=preview

watch: {
    filterSwitch () {
        // logs correctly with value of filterSwitch
        console.log('filterSwitch', this.filterSwitch)
        setTimeout(() => {
            // refresh header after value of floating filter has changed
            this.gridApi.refreshHeader()
        }, 0);
    }
},

这里有一些一般信息:Why is setTimeout(fn, 0) sometimes useful?

在 React(我知道)中我会使用 setState callback:

this.setState({
    filterSwitch: !filterSwitch,
}, () => {
    this.gridApi.refreshHeader();
});

我不知道是否有 Vue.js 等价物,但 setTimeout(..., 0) 完成了类似的事情。

For Angular: 文件后面的组件代码

 gridApi: any = null;
  floatingFilter = false;
  onGridReady(grid: any) {
    this.gridApi = grid.api;
  }
  toggleFloating(){
        this.floatingFilter = !this.floatingFilter;
         const columnDefs = this.gridApi.getColumnDefs();
         columnDefs.forEach((colDef:any, index:number)=> {
            colDef.floatingFilter = this.floatingFilter;
         });
         this.gridApi.setColumnDefs(columnDefs);
  }

Html:

 <ag-grid-angular style="width: 100%; height: 300px;" class="ag-theme-alpine" [rowData]="rowData" [gridOptions]="gridOptions"
        (gridReady)="onGridReady($event)">
    </ag-grid-angular>