Восстановление состояния колонки Ag Grid с реактивным редуксом - PullRequest
0 голосов
/ 10 февраля 2019

Я использую Ag Grid в приложении React + Redux.Мне нужно сделать состояние столбца постоянства сетки.Другими словами, каждый раз, когда пользователь вносит изменения в столбцы (порядок, сортировка, скрыть \ показывать и т. Д.), Приложение должно сохранять состояние столбца в БД.Затем, когда пользователь приходит снова, состояние столбца должно быть восстановлено.Мой подход состоит в том, чтобы использовать columnApi.getColumnState() для передачи состояния в БД при различных обратных вызовах событий и columnApi.setColumnState() в избыточном действии от componentDidMount.Я не получил никаких ошибок, однако состояние не применяется.Вот мой пример кода (я использую 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, поэтому он будет применен к моей сетке.Дело в том, что у меня был рабочий код перед тем, как перейти к редуксу.Приведенный ниже код работал, и состояние было применено правильно:

@(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 } />
  }
}

Так что я подозреваю, что я делаю что-то не так с Redx.Пожалуйста, помогите.

1 Ответ

0 голосов
/ 12 февраля 2019

Я думаю, я нашел решение.Это, вероятно, не самый элегантный, но это работаетДело в том, что я должен вызывать 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 } />
  }
}

Надеюсь, это кому-нибудь поможет.

...