2017-09-19 16 views
1

Ich habe jetzt für ein paar Stunden versucht, Sortierfunktionalität auf einem reaktiv-virtualisierten Tisch hinzuzufügen, kann aber nicht meinen Kopf drumherum ... hier ist die example und source code. Leider konnte ich kein PLNKR erstellen, daher habe ich einen Link zu meinem Github repo hinzugefügt.Wie füge ich Spaltensortierungsfunktionen zu meiner Tabelle hinzu?

ich diesen Fehler, wenn ich das Formular mit einem Eingabetext SCREW zum Beispiel einreichen:

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

Im Beispiel auf den site sie Kontext verwendet (const { list } = this.context;) anstelle von Requisiten. Vielleicht ist das das Problem?

Wenn ich this.props.list Konsolprotokoll ich die richtige Liste zu erhalten (siehe die beiden Beispieldokumente)

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

    // console.log(list); 

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

Hier sind zwei Objekte von meinem Server kommen und in 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" 
    } 
]; 

Hier ist die Code von 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) 
}; 

Antwort

1

Basierend auf der Tatsache, dass Ihr Code Referenzen auf list.length hat - scheint es, dass die list Prop, die Sie akzeptieren, ein Array sein könnte? Die Methode.(vorausgesetzt, Sie haben dies aus den reaktivierten virtualisierten Dokumenten aufgehoben) gehört zu einer Immutable JS List. Um ein JavaScript-Array zu sortieren, sollten Sie Array.prototype.sort verwenden.

PS. Der Code, den Sie eingefügt haben, hat noch ein paar andere Referenzen auf List Methoden (zB list.get(index)), die Sie mit Klammern ersetzen müssen (zB list[index]), wenn ich richtig bin, dass Sie ein Array verwenden.

Voll Code Lösung für PartTable.js (Bildquelle Autor)

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