使用React Redux恢复Ag Grid的列状态

时间:2019-02-10 04:36:50

标签: redux ag-grid ag-grid-react react-thunk

我在react + redux应用程序中使用Ag Grid。我需要使列状态为网格持久性。换句话说,每次用户对列进行更改(顺序,排序,隐藏\显示等)时,应用程序都必须将列状态保存到DB。然后,当用户再次出现时,必须恢复列状态。我的方法是使用columnApi.getColumnState()在各种事件回调上将状态推送到数据库,并在columnApi.setColumnState()的redux操作中使用componentDidMount。我没有错误,但是未应用状态。这是我的compoment示例代码(我正在使用react-thunk):

@(connect(selector, { getColumnStateAction, saveColumnStateAction }) as any)
class MyComponent extends Component<Props, {}> {

  private columnApi:any

  onGridReady(params) {
    const { columnState } = this.props
    params.columnApi.setColumnState(columnState)
    this.columnApi = params.columnApi
  } 

  onColumnChanged() {
    saveColumnStateAction(this.columnApi.getColumnState())
  }

  componentDidMount() {
    getColumnStateAction()
  }

  render() {        
    const { columnDefs } this.props
    const gridOptions = {
      columnDefs,
      onGridReady: this.onGridReady,
      onColumnVisible: this.onColumnChanged,
      onColumnResized: this.onColumnChanged,
      onColumnMoved: this.onColumnChanged,
      onColumnPinned: this.onColumnChanged
    }

    <AgGridReact { ...gridOptions } />
  }
}

这是我的动作:

const getColumnStateAction = () => async(dispatch:Dispatch) => {
   const columnState = await fetchFromDb();
   dispatch({ type:'GET_COLUMN_STATE', payload:columnState })
}

const saveColumnStateAction = (columnState:any) => async(dispatch:Dispatch) => {
   await saveToDb(columnState);
   dispatch({ type:'SAVE_COLUMN_STATE' })
}

我的问题是:我应该在何时何地恢复columnState以便将其应用于网格。关键是我在进行redux之前已经有了工作代码。下面的代码可以正常工作,并且状态已正确应用:

@(connect(selector, { getColumnStateAction, saveColumnStateAction }) as any)
class MyComponent extends Component<Props, {}> {

  private columnApi:any

  onGridReady(params) {
    this.columnApi = params.columnApi
  } 

  async onColumnChanged() {
    await saveToDb(this.columnApi.getColumnState());
  }

  async componentDidMount() {    
    const columnState = await fetchFromDb();
    this.columnApi.setColumnState(columnState)
  }

  render() {
    const { columnDefs } this.props
    const gridOptions = {
      columnDefs,
      onGridReady: this.onGridReady,
      onColumnVisible: this.onColumnChanged,
      onColumnResized: this.onColumnChanged,
      onColumnMoved: this.onColumnChanged,
      onColumnPinned: this.onColumnChanged
    }

    <AgGridReact { ...gridOptions } />
  }
}

所以我怀疑我在redux上做错了什么。请帮忙。

1 个答案:

答案 0 :(得分:0)

我认为,我已经找到了解决方案。它可能不是最优雅,但可以工作。关键是我必须在特定的时间(在columnApi.setColumnState()之后,componentDidMount之后以及网格中已经出现列的时候,才调用onGridReady。这是我的工作示例:

@(connect(selector, { getColumnStateAction, saveColumnStateAction }) as any)
  class MyComponent extends Component<Props, {}> {

  public state:any = { columnStateSet: false }

  private columnApi:any

  onGridReady(params) {
    const { columnState } = this.props
    this.columnApi = params.columnApi
  } 

  onColumnChanged() {
    saveColumnStateAction(this.columnApi.getColumnState())
  }

  /**
  * Catches a moment for applying persisted column state
  * The point is that previous columnState, that we get from DB, must be applied in specific moment.
  * It must be applied once per loading component after all columns are already set and columnApi becomes available.
  * Otherwise column state will not be applied correctly.
  */
  private onGridColumnsChanged = () => {
    const { columnStateSet } = this.state
    const { columnState } = this.props

    if(this.columnApi && columnState && !columnStateSet) {
      this.columnApi.setColumnState(columnState)
      this.setState({ columnStateSet: true})
    }
  }

  componentDidMount() {
    getColumnStateAction()
    this.setState({ columnStateSet: false })
  }

  render() {
    const { columnDefs } this.props
    const gridOptions = {
      columnDefs,
      onGridReady: this.onGridReady,
      onColumnVisible: this.onColumnChanged,
      onColumnResized: this.onColumnChanged,
      onColumnMoved: this.onColumnChanged,
      onColumnPinned: this.onColumnChanged,
      onGridColumnsChanged: this.onGridColumnsChanged
    }

    <AgGridReact { ...gridOptions } />
  }
}

希望对您有所帮助。