Created
July 12, 2017 08:20
-
-
Save buhichan/06431c11a06bdad0b6176ef874a68f7f to your computer and use it in GitHub Desktop.
Create a redux-driven server side pagination, filtering and sorting data grid with the power of ag-grid and my component ag-grid-material-preset
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Created by buhi on 2017/7/11. | |
*/ | |
import * as React from "react" | |
import {Grid,GridFieldSchema,GridProps} from "ag-grid-material-preset"; | |
import {IGetRowsParams} from "ag-grid/dist/lib/rowModels/iDatasource"; | |
import {GridApi} from "ag-grid/dist/lib/gridApi"; | |
import {List,Repeat} from "immutable"; | |
type InfiniteScrollGridProps = { | |
dispatch, | |
getAction:(payload:setDataPayload<any>)=>any, | |
getData:(payload:getDataParams<any>)=>Promise<[any[],number]>, | |
sum:number, | |
onError? | |
}&GridProps<any> | |
export type getDataParams<T> = {offset?:number,limit?:number,filter,sort}; | |
export type setDataPayload<T> = {data:T[],total:number,offset,limit} | |
export function handleInfiniteScrollGridSetDataAction<T>(oldData:List<T>,payload:setDataPayload<T>,):[List<T>,number]{ | |
const {offset,limit,data,total} = payload; | |
if(data === null) | |
return [null,total]; | |
else{ | |
if(oldData === null) | |
oldData = List(); | |
if(offset>=0 && limit>=0){ | |
if(oldData.size<offset) { | |
oldData = oldData.concat(Repeat({} as T,offset - oldData.size)); | |
} | |
return [oldData.splice(offset,data.length,...data),total]; | |
}else { | |
console.warn("Incorrect data in setWarnings",oldData,data); | |
return [oldData,total]; | |
} | |
} | |
} | |
export class InfiniteScrollGrid extends React.PureComponent<InfiniteScrollGridProps,any>{ | |
componentWillReceiveProps(nextProps:InfiniteScrollGridProps){ | |
if(nextProps.data!==this.props.data || nextProps.sum !==this.props.sum){ | |
if(nextProps.data===null){ | |
this.successCallBacks = {}; | |
this.api.setDatasource(this.dataSource); | |
}else{ | |
Object.keys(this.successCallBacks).forEach(offsetAsString=>{ | |
const offset = Number(offsetAsString); | |
this.successCallBacks[offset](nextProps.data.slice(offset,offset+this.limit),nextProps.sum); | |
}) | |
} | |
} | |
} | |
successCallBacks:{ | |
[offset:number]:Function | |
} = {}; | |
limit = 10; | |
dataSource={ | |
getRows:async (params:IGetRowsParams)=>{ | |
this.successCallBacks[params.startRow] = params.successCallback; | |
if(this.props.data&&this.props.data.length>params.startRow) | |
return params.successCallback(this.props.data.slice(params.startRow,params.endRow),this.props.sum); | |
try { | |
const offset = params.startRow; | |
const limit = params.endRow-offset; | |
const [data, total] = await this.props.getData({ | |
offset, | |
limit, | |
filter: params.filterModel, | |
sort: params.sortModel | |
}); | |
this.props.dispatch(this.props.getAction({ | |
data,total,offset,limit | |
})) | |
}catch(e){ | |
this.props.onError&&this.props.onError(e); | |
} | |
} | |
}; | |
api:GridApi; | |
render(){ | |
const {sum,gridApi,data,dispatch,getAction,getData,onError,...rest} = this.props; | |
return <Grid {...rest} | |
gridApi={api=>{ | |
this.api = api; | |
gridApi&&(gridApi as any)(api); | |
}} | |
rowModelType="infinite" | |
infiniteBlockSize={this.limit} | |
datasource={this.dataSource} | |
/> | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment