简体   繁体   English

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

[英]Toggle floating filter in Ag-Grid?

I am trying to have the display of the floating filter be determined by a switch or button click.我试图通过单击开关或按钮来确定浮动过滤器的显示。 Seems simple enough.看起来很简单。 I should just be able to toggle between true and false, supply that value to the floating filter in the grid options, and refresh the header right?我应该能够在 true 和 false 之间切换,将该值提供给网格选项中的浮动过滤器,然后刷新 header 对吗? Unfortunately, the grid always seems to be one step behind.不幸的是,网格似乎总是落后一步。 When I click the first time, nothing happens.当我第一次点击时,没有任何反应。 When I toggle the switch back to false is when the floating filter comes up.当我将开关切换回 false 时,浮动过滤器就会出现。 The floating filter will then continue to appear (when the switch is false) and disappear (when the switch is true).浮动过滤器将继续出现(当开关为 false 时)并消失(当开关为 true 时)。 To make things even weirder, if I toggle the floating filter switch a few times and then try toggling the rowGroupPanelShow (which I am also trying to have toggleable), it will trigger the floating filter to switch to whatever value it was not previously.为了让事情变得更奇怪,如果我切换浮动过滤器开关几次,然后尝试切换 rowGroupPanelShow(我也试图切换),它将触发浮动过滤器切换到它以前不是的任何值。 But only once.但只有一次。

I have tried a few variations on this.我已经尝试了一些变体。 I've tried switches and buttons.我试过开关和按钮。 I've tried watchers and writing my own functions to toggle true and false.我试过观察者并编写自己的函数来切换真假。 I've tried calling this.gridApi.refreshHeader() within the same function as the toggle and calling it from it's own function. I've tried calling this.columnApi.resetColumnState() (works for resetting grouping).我试过在与切换相同的 function 内调用this.gridApi.refreshHeader()并从它自己的 function 调用它。我试过调用this.columnApi.resetColumnState() (用于重置分组)。 Everything console logs correctly but the grid always seems to be one step behind.所有控制台都正确记录,但网格似乎总是落后一步。

Here's a link to a plunker that I took from ag-grid's website and modified to demonstrate the behavior: https://plnkr.co/edit/Me51NOVOCbmvFxx95WpP?p=preview这是我从 ag-grid 的网站上获取并修改以演示行为的 plunker 的链接: https://plnkr.co/edit/Me51NOVOCbmvFxx95WpP?p=preview

Here is the switch and the grid:这是开关和网格:

<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>

Here is the relevant bound data这是相关的绑定数据

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,

Here are the 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()
    },

Expected: Whether or not the floating filter is shown should be toggled by a switch.预期:浮动过滤器是否显示应由开关切换。 Passing the value of the switch to the grid and then refreshing the header should accomplish this.将开关的值传递给网格,然后刷新 header 应该可以完成此操作。

Actual: Grid seems to be one step behind (shows floating filter when switch is false).实际:网格似乎落后了一步(当开关为 false 时显示浮动过滤器)。

In my comment I suggested fixing it with setTimeout(..., 0) :在我的评论中,我建议使用setTimeout(..., 0)修复它:

https://plnkr.co/edit/9NAfPeEu8GgJw7okqz77?p=preview 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);
    }
},

Here's some general information: Why is setTimeout(fn, 0) sometimes useful?以下是一些一般信息:为什么 setTimeout(fn, 0) 有时有用?

In React (which I know) I would use the setState callback :在 React(我知道)中,我会使用setState回调

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

I don't know if there's a Vue.js equivalent, but setTimeout(..., 0) accomplishes a similar thing.我不知道是否有 Vue.js 等价物,但setTimeout(..., 0)完成了类似的事情。

For Angular: Component code behind file对于 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: html:

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

This may be a standard situation in React, where we need to use the useEffect hook, observing the change in the flag and then reacting to it.这可能是 React 中的标准情况,我们需要使用 useEffect 钩子,观察标志的变化,然后对其做出反应。

In the button or switch UI, the boolean flag isFilterOn is being toggled.在按钮或开关 UI 中,正在切换 boolean 标志 isFilterOn。 Then the filter is being toggled with the below code.然后使用以下代码切换过滤器。 Note that.注意。

import { useEffect, useState } from 'react'

... ...

// initial values for defaultColDef
// if filter is true, then we can skip setting it later
// defaultColDef: { filter: false, sortable: true, floatingFilter: false },

This is the flag which is toggled with a button click / etc这是通过单击按钮等切换的标志

const [isFilterOn, setIsFilterOn] = useState(false)

This is where we can hide or show the filter depending on the flag.这是我们可以根据标志隐藏或显示过滤器的地方。

  useEffect(() => {
    console.log('isFilterOn ' + isTableView)
    if (!gridOptions) return

    let colDefs = gridOptions.api.getColumnDefs()
    colDefs.forEach((colDef) => {
      colDef.floatingFilter = isFilterOn
      colDef.filter = isFilterOn
    })
    let columnDefs = colDefs
    gridOptions.api.setColumnDefs(columnDefs)
    gridOptions.api.refreshHeader()
  }, [isFilterOn])

Ref: plnkr where its implemented - shown in the last response (skip earlier responses) in this issue Ref: plnkr它的实现位置 - 显示在本期的最后一个回复中(跳过之前的回复)

useEffect hook in more detail. useEffect 钩子更详细。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM