2017-02-13 18 views
0

I(dBでログの数)は、公知の多数のTablerowCount設定さTableInfiniteLoaderとのバッチのサイズにInfiniteLoaderrowCountを実装する次の例を持っています私が取ったログ。私はこれが必要なので、ユーザーはスクロール高さに基づいてどれくらいのデータがあるかを知っています。それ以外の場合は、最後までスクロールして、さらにログがロードされているかどうかを確認する必要があります。私は2つのrowCountの小道具を悪用している可能性がありますが、データがまだロードされていない最後の近くのインデックスにスクロールすると、はgetRowClassName関数では未定義です。私はloadMoreRowsがこの場合呼び出されると仮定しました。未定義インデックスが呼び出され

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) 
       }); 
      }); 
    } 
}; 

答えて

0

は、私はあなたがInfiniteLoaderTableの両方に同じrowCount値を渡す必要があります2つのrowCount小道具

を悪用していますということでした。サーバー上のすべてのデータの合計サイズ(here)、またはユーザーが最後の近くでスクロールしたときにさらに多くのデータをロードできるようにローカルデータのサイズ+1(here)。

私はデータがまだロードされていないエンドに近い指標に高速でスクロールしたときに、データがgetRowClassName関数内で定義されていません。私はloadMoreRowsがこの場合呼び出されると仮定しました。

loadMoreRowsが呼び出されますが、非同期です。反応仮想化は、データが読み込まれるまでユーザーのスクロールをブロックしません。 getRowClassName関数は、遅延読み込みデータが読み込めるよりも速くスクロールできるという事実を処理する必要があります。必要に応じて、アンロードされた行に対して異なる「ロード中」UIを表示することができます。

+0

私は2つの 'rowCount'を使用している方法は正しいですか? – XeniaSis

+0

申し訳ありませんが、私はあなたの質問のその部分を逃した。私の答えを編集して詳細をいくつか追加しました。 – brianvaughn

+0

合計カウントを指定した最初のリンクでは、実際には同じカウントを使用していません。 'InfiniteLoader'は未定義の' remoteRowCount'を使用しますが、 'Table'は' list.length'を使用します – XeniaSis

関連する問題