Skip to content

Instantly share code, notes, and snippets.

@buhichan
Created July 12, 2017 08:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save buhichan/06431c11a06bdad0b6176ef874a68f7f to your computer and use it in GitHub Desktop.
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
/**
* 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