genannt Ich habe folgendes Beispiel die InfiniteLoader
mit einem Table
Implementierung, die die Table
rowCount
auf eine bekannte große Anzahl (Anzahl der Protokolle in der db) setzt und die InfiniteLoader
rowCount
auf die Größe des Charge Logs, die ich hole. Ich brauche das, damit der Benutzer weiß, wie viele Daten auf der Scroll-Höhe basieren. Andernfalls müsste er bis zum Ende scrollen und sehen, ob mehr Protokolle geladen sind. Könnte sein, dass ich die zwei rowCount
Requisiten missbrauche, aber wenn ich schnell zu einem Index nahe dem Ende scrollen, wo Daten noch nicht geladen sind, ist data
undefined in der getRowClassName
Funktion. Ich nahm an, die loadMoreRows
würde in diesem Fall aufgerufen werden.undefiniert Index nach loadMoreRows wird
import React = require('react');
import _ = require('lodash');
import Immutable = require('immutable');
import Api = require('./Api');
const STATUS_LOADING = 1,
STATUS_LOADED = 2,
LOG_LIMIT = 200;
interface Props {
logEntries: Immutable.List<Immutable.Map<string, any>>;
}
interface State {
logEntries?: Immutable.List<Immutable.Map<string, any>>;
count?: number;
loadedRowsMap?: any;
}
class LogViewer extends React.Component<Props, State> {
constructor(props: Props) {
super(props);
this.state = {
logEntries: props.logEntries,
count: 0,
loadedRowsMap: {}
};
}
render() {
return {this.renderLoader()};
}
private renderLoader() {
const {logEntries, count} = this.state;
return (
<InfiniteLoader isRowLoaded={this.isRowLoaded.bind(this)}
loadMoreRows={this.loadMoreRows.bind(this)}
minimumBatchSize={LOG_LIMIT}
rowCount={logEntries.size} >
{
({onRowsRendered, registerChild}) => (
<AutoSizer disableHeight>
{
({width}) => (
<Table headerHeight={20}
height={400}
onRowsRendered={onRowsRendered}
ref={registerChild}
rowCount={count}
className='log-entries'
gridClassName='grid'
rowClassName={this.getRowClassName.bind(this)}
headerStyle={{ fontSize: 15 }}
rowGetter={({index}) => logEntries.get(index)}
rowHeight={50}
width={width} >
<Column label='Name'
key='name'
dataKey='name'
width={200} />
</Table>
)
}
</AutoSizer>
)
}
</InfiniteLoader>
);
}
private getRowClassName({index}) {
const {logEntries} = this.state;
if(index > -1) {
const data = logEntries.get(index);
return `log-entry ${data.get('name').toLowerCase()}`;
}
return '';
}
private isRowLoaded({index}) {
const {loadedRowsMap} = this.state;
return !!loadedRowsMap[index];
}
private loadMoreRows({startIndex, stopIndex}) {
const {loadedRowsMap, level, logEntries} = this.state;
_.range(startIndex, stopIndex).forEach(i => {
loadedRowsMap[i] = STATUS_LOADING;
});
this.setState({ loadedRowsMap });
const offset = Math.floor((startIndex + 1)/LOG_LIMIT);
return Api.logs(LOG_LIMIT, offset)
.then(({body: [count, logs]}) => {
_.range(startIndex, stopIndex).forEach(i => {
loadedRowsMap[i] = STATUS_LOADED;
});
const newLogs = logEntries.toJS().concat(logs);
this.setState({
count,
logEntries: Immutable.fromJS(newLogs)
});
});
}
};
Also, die Art, wie ich die 2 'rowCount's verwende, ist korrekt? – XeniaSis
Entschuldigung, ich habe diesen Teil Ihrer Frage verpasst. Bearbeitete meine Antwort, um etwas mehr Details zu enthalten. – brianvaughn
Auf der ersten Verknüpfung, die Sie mit der Gesamtzahl angegeben haben, wird nicht dieselbe Anzahl verwendet. Der 'InfiniteLoader' verwendet ein undefiniertes' remoteRowCount', während die 'Tabelle' das' list.length' verwendet. – XeniaSis