我在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上做错了什么。请帮忙。
答案 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 } />
}
}
希望对您有所帮助。