2017-09-19 59 views
1

我已經嘗試了幾個小時在反應虛擬化桌面上添加排序功能,但是無法繞過它...這裏是examplesource code。對不起,我無法創建一個plnkr,所以我附上了一個鏈接到我的github repo如何將列排序功能添加到我的表中?

我得到這個錯誤,當我和一個輸入文本螺絲提交表單,例如:

TypeError: list.sortBy is not a function 
    at PartTable._sortList (PartTable.js:136) 
    at new PartTable (PartTable.js:18) 

在上site他們使用上下文(const { list } = this.context;)的例子,而不是道具。也許這是問題?

當我控制檯登錄this.props.list我得到正確的列表(見兩個示例文件)

_sortList({ sortBy, sortDirection }) { 
    const { list } = this.props; 

    // console.log(list); 

    return list 
     .sortBy(item => item[sortBy]) 
     .update(
     list => (sortDirection === SortDirection.DESC ? list.reverse() : list) 
    ); 
    } 

下面是兩個對象從我的服務器,併爲未來的props.list

[ 
    { 
    customsTariff: "73181568", 
    facility: "SDC", 
    netWeight: "0,07", 
    partName: "CAPSCREW", 
    partNumber: "3121210233", 
    __v: 0, 
    _id: "59a9429ac0b7467bf084eb6e" 
    }, 
    { 
    customsTariff: "73481568", 
    facility: "SDC", 
    netWeight: "0,08", 
    partName: "CAPSCREW2", 
    partNumber: "3121210333", 
    __v: 0, 
    _id: "59a9429ac0b7463bf084eb6e" 
    } 
]; 

這裏是來自PartTable.js的代碼

import React, { PureComponent } from "react"; 
import { AutoSizer, Column, Table } from "react-virtualized"; 
import { CSVLink, CSVDownload } from "react-csv"; 
import Button from "material-ui/Button"; 
import PropTypes from "prop-types"; 
import SortDirection from "./SortDirection"; 
import SortIndicator from "./SortIndicator"; 
import Checkbox from "material-ui/Checkbox"; 
import "react-virtualized/styles.css"; 
import "../../styles/App.css"; 
import styles from "./Table.example.css"; 

export default class PartTable extends PureComponent { 
    constructor(props) { 
    super(props); 
    const sortBy = "partNumber"; // I want to sort by partNumber by default 
    const sortDirection = SortDirection.ASC; 
    const sortedList = this._sortList({ sortBy, sortDirection }); 

    this.state = { 
     sortBy, 
     sortDirection, 
     rowCount: 1000, 
     sortedList 
    }; 
    this._noRowsRenderer = this._noRowsRenderer.bind(this); 
    this._generateCheckbox = this._generateCheckbox.bind(this); 
    this._sort = this._sort.bind(this); 
    } 

    render() { 
    // console.log(this.props.list); 
    const { sortBy, sortDirection, sortedList } = this.state; 
    const rowGetter = ({ index }) => this._getDatum(sortedList, index); 
    const { list, headers } = this.props; 
    return (
     <div> 
     <AutoSizer disableHeight> 
      {({ width }) => (
      <Table 
       width={width} 
       height={500} 
       headerHeight={50} 
       rowHeight={50} 
       rowCount={list.length} 
       rowGetter={rowGetter} 
       noRowsRenderer={this._noRowsRenderer} 
       sort={this._sort} 
       sortBy={sortBy} 
       sortDirection={sortDirection} 
      > 
       {headers.map(header => { 
       return (
        <Column 
        key={header.id} 
        label={header.label} 
        dataKey={header.id} 
        disableSort 
        width={100} 
        flexGrow={1} 
        cellRenderer={ 
         header.index ? this._generateCheckbox : undefined 
        } 
        /> 
       ); 
       })} 
      </Table> 
     )} 
     </AutoSizer> 
     <CSVLink data={list}> 
      <Button color="accent">Export {list.length} records to CSV</Button> 
     </CSVLink> 
     </div> 
    ); 
    } 

    _noRowsRenderer() { 
    return <div>No Parts here...</div>; 
    } 
    _generateCheckbox(event) { 
    // console.log(event); 
    return (
     <div className="table-check-box"> 
     {this.props.activeCheckboxes && (
      <Checkbox 
      onChange={() => this.props._activeCheckbox(event.rowData._id)} 
      checked={this.props.activeCheckboxes.includes(event.rowData._id)} 
      /> 
     )} 
     {event.cellData} 
     </div> 
    ); 
    } 
    _isSortEnabled() { 
    const { list } = this.props; 
    const { rowCount } = this.state; 
    return rowCount <= list.size; 
    } 

    _getDatum(list, index) { 
    return list.get(index % list.size); 
    } 

    _sort({ sortBy, sortDirection }) { 
    const sortedList = this._sortList({ sortBy, sortDirection }); 

    this.setState({ sortBy, sortDirection, sortedList }); 
    } 

    _sortList({ sortBy, sortDirection }) { 
    const { list } = this.props; 

    // console.log(list); 

    return list 
     .sortBy(item => item[sortBy]) 
     .update(
     list => (sortDirection === SortDirection.DESC ? list.reverse() : list) 
    ); 
    } 
    _rowClassName({ index }) { 
    if (index < 0) { 
     return styles.headerRow; 
    } else { 
     return index % 2 === 0 ? styles.evenRow : styles.oddRow; 
    } 
    } 
} 

PartTable.PropTypes = { 
    list: PropTypes.arrayOf({}).isRequired, 
    activeCheckboxes: PropTypes.arrayOf({}), 
    _activeCheckbox: PropTypes.func, 
    headers: PropTypes.arrayOf({}.isRequired) 
}; 

回答

1

根據您的代碼提及list.length的事實 - 您接受的list prop似乎可能是Array? sortBy方法(假設您從反應虛擬化文檔中解除了這一點)屬於Immutable JS List。要排序JavaScript數組,您需要使用Array.prototype.sort

PS。如果我正確地使用數組,則您粘貼的代碼還有其他一些對List方法(例如list.get(index))的引用,您將要用括號替換(例如list[index])。

爲PartTable.js 完整代碼溶液(由作者提供)

import React, { PureComponent } from "react"; 
import { 
    AutoSizer, 
    Column, 
    Table, 
    SortDirection, 
    SortIndicator 
} from "react-virtualized"; 
import { CSVLink, CSVDownload } from "react-csv"; 
import Button from "material-ui/Button"; 
import PropTypes from "prop-types"; 
import Checkbox from "material-ui/Checkbox"; 
import "react-virtualized/styles.css"; 
import "../../styles/App.css"; 
import styles from "./Table.example.css"; 

export default class PartTable extends PureComponent { 
    constructor(props) { 
    super(props); 

    const sortBy = "partNumber"; 
    const sortDirection = SortDirection.ASC; 
    const sortedList = this._sortList({ sortBy, sortDirection }); 

    this.state = { 
     list: this.props.list, 
     sortBy, 
     sortDirection, 
     sortedList, 
     rowCount: 1000 
    }; 
    this._noRowsRenderer = this._noRowsRenderer.bind(this); 
    this._generateCheckbox = this._generateCheckbox.bind(this); 
    this._sort = this._sort.bind(this); 
    } 

    render() { 
    const { headers } = this.props; 
    const { list, sortBy, sortDirection, sortedList, rowCount } = this.state; 

    const rowGetter = ({ index }) => this._getDatum(sortedList, index); 

    return (
     <div> 
     <AutoSizer disableHeight> 
      {({ width }) => (
      <Table 
       width={width} 
       height={500} 
       headerHeight={50} 
       rowHeight={50} 
       rowClassName={this._rowClassName} 
       rowCount={rowCount} 
       rowGetter={({ index }) => list[index]} // ({ index }) => list[index] 
       noRowsRenderer={this._noRowsRenderer} 
       onHeaderClick={this._sortByClickedHeader} 
       sort={this._sort} 
       sortBy={sortBy} 
       sortDirection={sortDirection} 
      > 
       {headers.map(header => { 
       return (
        <Column 
        key={header.id} 
        label={header.label} 
        dataKey={header.id} 
        width={100} 
        flexGrow={1} 
        cellRenderer={ 
         header.index ? this._generateCheckbox : undefined 
        } 
        /> 
       ); 
       })} 
      </Table> 
     )} 
     </AutoSizer> 
     <CSVLink data={list}> 
      <Button color="accent">Export {list.length} records to CSV</Button> 
     </CSVLink> 
     </div> 
    ); 
    } 

    _getDatum(list, index) { 
    return list[index]; 
    } 

    _sort({ sortBy, sortDirection }) { 
    const sortedList = this._sortList({ sortBy, sortDirection }); 

    this.setState({ sortBy, sortDirection, sortedList }); 
    } 

    _sortList({ sortBy, sortDirection }) { 
    const { list } = this.props; 
    if (sortBy) { 
     let updatedList = 
     // sort by name 
     list.sort(function(a, b) { 
      var nameA = a[sortBy].toUpperCase(); // ignore upper and lowercase 
      var nameB = b[sortBy].toUpperCase(); // ignore upper and lowercase 
      if (nameA < nameB) { 
      return -1; 
      } 
      if (nameA > nameB) { 
      return 1; 
      } 
      // names must be equal 
      return 0; 
     }); 
     sortDirection === SortDirection.DESC 
     ? updatedList.reverse() 
     : updatedList; 
    } 
    } 

    _noRowsRenderer() { 
    return <div>No Parts here...</div>; 
    } 
    _generateCheckbox(event) { 
    // console.log(event); 
    return (
     <div className="table-check-box"> 
     {this.props.activeCheckboxes && (
      <Checkbox 
      onChange={() => this.props._activeCheckbox(event.rowData._id)} 
      checked={this.props.activeCheckboxes.includes(event.rowData._id)} 
      /> 
     )} 
     {event.cellData} 
     </div> 
    ); 
    } 
} 

PartTable.PropTypes = { 
    list: PropTypes.arrayOf({}).isRequired, 
    activeCheckboxes: PropTypes.arrayOf({}), 
    _activeCheckbox: PropTypes.func, 
    headers: PropTypes.arrayOf({}.isRequired) 
}; 
相關問題