2017-02-13 10 views
0

У меня есть следующий пример, реализующий InfiniteLoader с Table который устанавливающее TablerowCount к известному большому количеству (количество бревен в БД) и InfiniteLoaderrowCount до размера партии я беру журналы. Мне нужно это, чтобы пользователь знал, сколько данных существует на основе списка прокрутки. В противном случае ему придется прокручивать до конца и посмотреть, загружено ли больше журналов. Может быть, я злоупотребляю двумя реквизитами rowCount, но всякий раз, когда я быстро прокручиваю индекс до конца, где данные еще не загружены, data не определен в функции getRowClassName. Я предположил, что loadMoreRows будет вызван в этом случае.Неопределенного индекс после того, как 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

Может быть, что я злоупотребляя два rowCount реквизита

Вы должны пройти тот же rowCount значение как InfiniteLoader и Table. Это должен быть либо общий размер всех ваших данных на сервере (как показано here), либо размер ваших локальных данных +1, чтобы разрешить загрузку больше, когда пользователь прокручивается ближе к концу (как показано here).

всякий раз, когда я прокрутки быстро, чтобы индекс, близкий к концу, где данные еще не загружен, данные не определен в функции getRowClassName. Я предположил, что loadMoreRows будет вызван в этом случае.

loadMoreRows действительно называется, но это асинхронный. virtual-virtual не будет блокировать прокрутку пользователя, пока данные не загрузятся. Функция getRowClassName должна обрабатывать тот факт, что пользователь может прокручиваться быстрее, чем ваши ленивые данные могут загружаться. Вы можете отобразить другой пользовательский интерфейс «load in progress» для разгруженных строк, если хотите.

+0

Итак, способ, которым я использую 2 'rowCount', является правильным? – XeniaSis

+0

Извините, я пропустил эту часть вашего вопроса. Отредактировал мой ответ, чтобы включить более подробную информацию. – brianvaughn

+0

На первой ссылке, которую вы указали с общим счетом, на самом деле не используется тот же счет. 'InfiniteLoader' использует неопределенный' remoteRowCount', в то время как 'Таблица' использует' list.length' – XeniaSis