ReactJS FixedDataTable 排序和过滤示例不起作用
Posted
技术标签:
【中文标题】ReactJS FixedDataTable 排序和过滤示例不起作用【英文标题】:ReactJS FixedDataTable sorting and filtering example not working 【发布时间】:2017-04-17 09:32:45 【问题描述】:我正在尝试遵循这个 ReactJS 教程:
第 1 部分:http://4dev.tech/2015/12/reactjs-datatable-with-sort-filter-and-pagination-example-part-1/
第 2 部分:http://4dev.tech/2016/03/tutorial-sorting-and-filtering-a-reactjs-datatable/
我成功完成了第 1 部分,我需要一些帮助才能完成第 2 部分。
这是我的第 2 部分代码:
import React from 'react';
import Table, Column, Cell from 'fixed-data-table';
class MyTable extends React.Component
constructor(props)
super(props);
this.rows = ["id":1,"first_name":"William","last_name":"Elliott","email":"welliott0@wisc.edu",
"country":"Argentina","ip_address":"247.180.226.89",
"id":2,"first_name":"Carl","last_name":"Ross","email":"cross1@mlb.com",
"country":"South Africa","ip_address":"27.146.70.36",
"id":3,"first_name":"Jeremy","last_name":"Scott","email":"jscott2@cbsnews.com",
"country":"Colombia","ip_address":"103.52.74.225",
]
this.state =
filteredDataList: this.rows
;
_renderHeader(label, cellDataKey)
return <div>
<span>label</span>
<div>
<br />
<input style=width:90+'%' onChange=this._onFilterChange.bind(this, cellDataKey)/>
</div>
</div>;
_onFilterChange(cellDataKey, event)
if (!event.target.value)
this.setState(
filteredDataList: this.rows,
);
var filterBy = event.target.value.toString().toLowerCase();
var size = this.rows.length;
var filteredList = [];
for (var index = 0; index < size; index++)
var v = this.rows[index][cellDataKey];
if (v.toString().toLowerCase().indexOf(filterBy) !== -1)
filteredList.push(this.rows[index]);
this.setState(
filteredDataList: filteredList,
);
render()
return <Table
height=40+((this.rows.length+1) * 30)
width=1150
rowsCount=this.rows.length
rowHeight=30
headerHeight=30
rowGetter=function(rowIndex) return this.rows[rowIndex]; .bind(this)>
<Column dataKey="id" width=50 label="Id"
headerRenderer=this._renderHeader.bind(this)/>
<Column dataKey="first_name" width=200 label="First Name" />
<Column dataKey="last_name" width=200 label="Last Name" />
<Column dataKey="email" width=400 label="e-mail" />
<Column dataKey="country" width=300 label="Country" />
</Table>;
module.exports = MyTable;
数据表显示,但不显示用于过滤行的输入字段。
浏览器控制台没有显示任何错误,除了一些警告:
`rowGetter` will be DEPRECATED in version 0.7.0 of FixedDataTable and beyond.
Please use the cell API in Column to fetch data for your cells.
Read the docs at: https://fburl.com/FixedDataTable-v0.6
`label` will be DEPRECATED in version 0.7.0 of FixedDataTable and beyond.
Please use `header` instead.
Read the docs at: https://fburl.com/FixedDataTable-v0.6
`dataKey` will be DEPRECATED in version 0.7.0 of FixedDataTable and beyond.
Please use the `cell` API to pass in a dataKey
Read the docs at: https://fburl.com/FixedDataTable-v0.6
`headerRenderer` will be DEPRECATED in version 0.7.0 of FixedDataTable and beyond.
Please use the `header` API to pass in a React Element instead.
Read the docs at: https://fburl.com/FixedDataTable-v0.6
我不知道问题是什么。 感谢您的宝贵时间。
【问题讨论】:
【参考方案1】:这个问题与您的固定数据表版本有关。请在此处查看此 v0.6 API 迁移:https://facebook.github.io/fixed-data-table/v6-migration.html
【讨论】:
请注意:网站可以下线;链接可能会中断。你的回答变得毫无用处。因此:避免仅提供链接的答案,并至少提供一定程度的详细信息。【参考方案2】:虽然这个问题已经有一年了,但我最近遇到了类似的麻烦,可以分享我的经验。另外,我不知道您对 React 的熟悉程度如何,但我会尝试以对初学者友好的方式进行解释以帮助其他人,如果有任何明显的地方请多多包涵。
因此,您遇到的浏览器错误是由于另一个答案中提到的 API 更改造成的。您引用的教程使用的是旧 API。新的 API 更改涉及一些事情。也就是说,您将无法再访问 rowGetter
、headerDataGetter
、headerRenderer
、dataKey
和 label
等。
新的 API 涉及将数据直接提供到单元组件中,我将对此进行演示。
首先,您现在可以制作自定义单元格,这样您就可以将它们设置为具有您想要的行为。我们将创建一个文本单元格类MyTextCell
来显示网格内的文本,以及一个标题单元格类SortHeaderCell
,我们可以单击它来对列进行排序,并显示一个显示排序顺序的箭头。您也可以为您的电子邮件列添加自定义单元格类,以创建电子邮件地址链接。
我将首先介绍排序,因为我认为它更难。这基本上使用与文档中的示例相同的方法。
现在你现在拥有的数据只是一个数组,这很好。但是,文档使用 DataListWrapper 类,它有一个包含您的数据的 _data
属性,以及另一个用于排序索引的 _indexMap
属性,所以让我们这样做(请注意,如果您正在查看文档中的示例,我稍微改了一下):
class DataListWrapper
constructor(indexMap, data)
this._indexMap = indexMap;
this._data = data;
getSize()
return this._indexMap.length;
getObjectAt(index)
let sortedIdx = this._indexMap[index];
return this._data[sortedIdx];
您可以将前面提到的自定义单元格类型制作为无状态组件,例如我们的自定义文本单元格:
const MyTextCell = ( rowIndex, field, data, ...props ) =>
return (
<Cell ...props>
data.getObjectAt(rowIndex)[field]
</Cell>
);
或者,您可以像在此自定义排序标题单元格中一样使它们有状态。没有理由各有一个,我只是想展示这两种选择:
class SortHeaderCell extends React.Component
constructor(props)
super(props);
this._onSortChange = this._onSortChange.bind(this);
render()
let onSortChange, sortDir, children, ...props = this.props;
console.log(this.props)
return (
<Cell ...props>
<a onClick=this._onSortChange>
children sortDir ? (sortDir === SortTypes.DESC ? '↓' : '↑') : ''
</a>
</Cell>
);
_onSortChange(e)
e.preventDefault();
if (this.props.onSortChange)
this.props.onSortChange(
this.props.columnKey,
this.props.sortDir ?
reverseSortDirection(this.props.sortDir) :
SortTypes.DESC
);
您还需要创建排序类型:
const SortTypes =
ASC: 'ASC',
DESC: 'DESC',
;
还有一种快速反转排序类型的方法:
function reverseSortDirection(sortDir)
return sortDir === SortTypes.DESC ? SortTypes.ASC : SortTypes.DESC;
有一点需要注意——我们在标题中有一个_onSortChange
方法,用于显示箭头并调用实际对数据进行排序的方法,但该方法将在实际的表格组件中。
在你的桌子上,你需要一些东西。
在您的情况下,您的表数据是硬编码的,但最佳做法是通过道具传递它。假设您通过属性获取数据,您需要相应地设置状态并设置默认排序索引(基本上是数据最初的排序方式)。
componentWillReceiveProps(props)
this._defaultSortIndexes = [];
var size = props.myDataArray.length;
for (var index = 0; index < size; index++)
this._defaultSortIndexes.push(index);
this.setState( myTableData: props.myDataArray, sortedFilteredDataList: new DataListWrapper(this._defaultSortIndexes, props.myDataArray) )
所以,现在您的标题知道如何显示箭头以及如何调用表格本身的_onSortChange
方法。你的 table 组件也知道如何通过 props 接收数据数组,并将其放入 DataWrapper,并将其添加到 state。所以我们必须在表中创建 _onSortChange
方法,它实际上会将数据包装器中的 sortIndexes 设置为正确的顺序:
_onSortChange(columnKey, sortDir)
var sortIndexes = this._defaultSortIndexes.slice();
sortIndexes.sort((indexA, indexB) =>
var valueA = this.state.myTableData[indexA][columnKey];
var valueB = this.state.myTableData[indexB][columnKey];
var sortVal = 0;
if (valueA > valueB)
sortVal = 1;
if (valueA < valueB)
sortVal = -1;
if (sortVal !== 0 && sortDir === SortTypes.ASC)
sortVal = sortVal * -1;
return sortVal;
);
this.setState(
sortedFilteredDataList: new DataListWrapper(sortIndexes, this.state.myTableData),
colSortDirs:
[columnKey]: sortDir,
,
);
所以现在,您可以像这样设置列:
<Column
columnKey='country'
header=
<SortHeaderCell
onSortChange=this._onSortChange
sortDir=colSortDirs.country>
Country
</SortHeaderCell>
cell=
<MyTextCell
data=this.state.sortedFilteredDataList
field="country"
/>
width=150
/>
排序就差不多了。文档演示了一种类似的过滤方式,使用带有过滤器索引的 DataListWrapper。我没有这样做,只是在我的表格组件嵌套的组件中过滤了我的数据数组。本质上,我有一个组件负责通过 props 将数据传递给 table 组件,并在那里进行过滤。我是这样做的:
在父组件中,我有一个过滤/搜索方法:
filterSearch(searchTerm)
this.setState(
filteredData: this.state.myData.filter(function (el)
return (el.propertyToFilter.includes(searchTerm) || !searchTerm);
)
);
然后我渲染我的搜索组件和我的表格组件:
<div>
<div>
<SearchBox onSearchTermChange=this.filterSearch />
</div>
<br />
<div className="row">
<div>
<ResultsTable myDataArray=this.state.filteredData />
</div>
</div>
</div>
我的搜索框组件是这样的:
class SearchBox extends Component
constructor(props)
super(props);
this.state= term: '';
render()
return (
<div>
<input
value=this.state.term
onChange=(e)=>this.onInputChange(e.target.value)></input>
</div>
)
onInputChange(term)
this.setState(term);
this.props.onSearchTermChange(term);
export default SearchBox;
差不多就是这样。您还应该注意,现在不支持fixed-data-table,您应该使用fixed-data-table-2。也就是说,我在固定数据表中完成了上述所有操作,它应该可以工作。
文档方面,官方文档为here
这些链接虽然是旧示例,但有一些错误。新的例子是here
【讨论】:
以上是关于ReactJS FixedDataTable 排序和过滤示例不起作用的主要内容,如果未能解决你的问题,请参考以下文章
将 LeafletJS 与 ReactJS 一起使用时,Tiles 未正确排序