React fixed-data-table: Uncaught TypeError: this._dataList.getSize is not a function
React fixed-data-table: Uncaught TypeError: this._dataList.getSize is not a function
我正在尝试使用 React 开发人员的 this example 来为 table.
创建一个搜索过滤器
我有 table 可以很好地静态处理来自后端的数据。我已经为 "sample" 数据取出了一个数组以使搜索功能正常工作。但是我很难理解他们如何使用 "fake data" 将他们的 table 填充为 seen here,这与 "just" 用测试数组填充它相反如我所愿。
这是我的源代码。我想通过 "firstName" 列进行过滤,就像在 Facebook 的示例中一样(为简单起见)。错误源于调用 getSize() 时......但我怀疑问题出在其他地方。
class DataListWrapper {
constructor(indexMap, data) {
this._indexMap = indexMap;
this._data = data;
}
getSize() {
return this._indexMap.length;
}
getObjectAt(index) {
return this._data.getObjectAt(
this._indexMap[index],
);
}
}
class NameTable extends React.Component {
constructor(props) {
super(props);
this.testDataArr = []; // An array.
this._dataList = this.testDataArr;
console.log(JSON.stringify(this._dataList)); // It prints the array correctly.
this.state = {
filteredDataList: new DataListWrapper([], this._dataList)
};
this._onFilterChange = this._onFilterChange.bind(this);
}
_onFilterChange(e) {
if (!e.target.value) {
this.setState({
filteredDataList: this._dataList,
});
}
var filterBy = e.target.value;
var size = this._dataList.getSize();
var filteredIndexes = [];
for (var index = 0; index < size; index++) {
var {firstName} = this._dataList.getObjectAt(index);
if (firstName.indexOf(filterBy) !== -1) {
filteredIndexes.push(index);
}
}
this.setState({
filteredDataList: new DataListWrapper(filteredIndexes, this._dataList),
});
}
render() {
var filteredDataList = this.state.filteredDataList;
if (!filteredDataList) {
return <div>Loading table.. </div>;
}
var rowsCount = filteredDataList.getSize();
return (
<div>
<input onChange={this._onFilterChange} type="text" placeholder='Search for first name.. ' />
{/*A table goes here, which renders fine normally without the search filter. */}
</div>
);
}
}
export default NameTable
您的问题出在 _onFilterChange
方法中。
您正在这样做:
var size = this._dataList.getSize();
this._dataList
只是一个数组,这就是该对象中不存在 getSize() 的原因。
如果我没有误会你应该这样做:
var size = this.state.filteredDataList.getSize();
循环内也会发生同样的情况,你正在这样做:
var {firstName} = this._dataList.getObjectAt(index);
什么时候应该这样做:
var {firstName} = this.state.filteredDataList.getObjectAt(index);
您的 _onFilterChange 方法应如下所示:
_onFilterChange(e) {
if (!e.target.value) {
this.setState({
filteredDataList: this._dataList,
});
}
var filterBy = e.target.value;
//var size = this._dataList.getSize();
var size = this.state.filteredDataList.getSize();
var filteredIndexes = [];
for (var index = 0; index < size; index++) {
//var {firstName} = this._dataList.getObjectAt(index);
var {firstName} = this.state.filteredDataList.getObjectAt(index);
if (firstName.indexOf(filterBy) !== -1) {
filteredIndexes.push(index);
}
}
this.setState({
filteredDataList: new DataListWrapper(filteredIndexes, this._dataList),
});
}
getSize() 和 getObjectAt() 只能在实现这些方法的数据对象上调用,例如 DataListWrapper 对象。
如果您将纯数据数组传递给 render(),则它不会提供 getSize() 和 getElementAt() 方法,并且对这些方法的调用将失败。
原始演示之所以有效,是因为 FakeObjectDataListStore 数据是一个实现 getSize 和 getObjectAt 方法的对象('FakeObjectDataListStore')。
最简单的集成是确保传入的数据是提供这些方法的对象。基于我在 'examples/FilterExample' 上的案例,我发现最简单的集成(在与许多糟糕的问题作斗争之后)是将现有的 'helpers/FakeObjectDataListStore.js' 变成我自己的 helpers/ObjectDataListStore.js(或选择你的名字)因此在整个设计中保留现有的方法包装结构和大小参数。然后,我简单地将对 'fake' 组件的调用替换为对我自己的非包装本地列表行数组的引用。您可以将本地数据安排为静态数据,或从您使用的任何数据库环境中动态加载。然后很容易修改 _setFiltered() 方法以过滤 'firstName'.
以外的内容
FixedDataTable 最酷的地方在于它能够浏览大型列表,
并且开发人员可以编写自己的自定义单元格渲染器,例如在列表行中的任意位置显示进度条、按钮或菜单。
我正在尝试使用 React 开发人员的 this example 来为 table.
创建一个搜索过滤器我有 table 可以很好地静态处理来自后端的数据。我已经为 "sample" 数据取出了一个数组以使搜索功能正常工作。但是我很难理解他们如何使用 "fake data" 将他们的 table 填充为 seen here,这与 "just" 用测试数组填充它相反如我所愿。
这是我的源代码。我想通过 "firstName" 列进行过滤,就像在 Facebook 的示例中一样(为简单起见)。错误源于调用 getSize() 时......但我怀疑问题出在其他地方。
class DataListWrapper {
constructor(indexMap, data) {
this._indexMap = indexMap;
this._data = data;
}
getSize() {
return this._indexMap.length;
}
getObjectAt(index) {
return this._data.getObjectAt(
this._indexMap[index],
);
}
}
class NameTable extends React.Component {
constructor(props) {
super(props);
this.testDataArr = []; // An array.
this._dataList = this.testDataArr;
console.log(JSON.stringify(this._dataList)); // It prints the array correctly.
this.state = {
filteredDataList: new DataListWrapper([], this._dataList)
};
this._onFilterChange = this._onFilterChange.bind(this);
}
_onFilterChange(e) {
if (!e.target.value) {
this.setState({
filteredDataList: this._dataList,
});
}
var filterBy = e.target.value;
var size = this._dataList.getSize();
var filteredIndexes = [];
for (var index = 0; index < size; index++) {
var {firstName} = this._dataList.getObjectAt(index);
if (firstName.indexOf(filterBy) !== -1) {
filteredIndexes.push(index);
}
}
this.setState({
filteredDataList: new DataListWrapper(filteredIndexes, this._dataList),
});
}
render() {
var filteredDataList = this.state.filteredDataList;
if (!filteredDataList) {
return <div>Loading table.. </div>;
}
var rowsCount = filteredDataList.getSize();
return (
<div>
<input onChange={this._onFilterChange} type="text" placeholder='Search for first name.. ' />
{/*A table goes here, which renders fine normally without the search filter. */}
</div>
);
}
}
export default NameTable
您的问题出在 _onFilterChange
方法中。
您正在这样做:
var size = this._dataList.getSize();
this._dataList
只是一个数组,这就是该对象中不存在 getSize() 的原因。
如果我没有误会你应该这样做:
var size = this.state.filteredDataList.getSize();
循环内也会发生同样的情况,你正在这样做:
var {firstName} = this._dataList.getObjectAt(index);
什么时候应该这样做:
var {firstName} = this.state.filteredDataList.getObjectAt(index);
您的 _onFilterChange 方法应如下所示:
_onFilterChange(e) {
if (!e.target.value) {
this.setState({
filteredDataList: this._dataList,
});
}
var filterBy = e.target.value;
//var size = this._dataList.getSize();
var size = this.state.filteredDataList.getSize();
var filteredIndexes = [];
for (var index = 0; index < size; index++) {
//var {firstName} = this._dataList.getObjectAt(index);
var {firstName} = this.state.filteredDataList.getObjectAt(index);
if (firstName.indexOf(filterBy) !== -1) {
filteredIndexes.push(index);
}
}
this.setState({
filteredDataList: new DataListWrapper(filteredIndexes, this._dataList),
});
}
getSize() 和 getObjectAt() 只能在实现这些方法的数据对象上调用,例如 DataListWrapper 对象。
如果您将纯数据数组传递给 render(),则它不会提供 getSize() 和 getElementAt() 方法,并且对这些方法的调用将失败。
原始演示之所以有效,是因为 FakeObjectDataListStore 数据是一个实现 getSize 和 getObjectAt 方法的对象('FakeObjectDataListStore')。
最简单的集成是确保传入的数据是提供这些方法的对象。基于我在 'examples/FilterExample' 上的案例,我发现最简单的集成(在与许多糟糕的问题作斗争之后)是将现有的 'helpers/FakeObjectDataListStore.js' 变成我自己的 helpers/ObjectDataListStore.js(或选择你的名字)因此在整个设计中保留现有的方法包装结构和大小参数。然后,我简单地将对 'fake' 组件的调用替换为对我自己的非包装本地列表行数组的引用。您可以将本地数据安排为静态数据,或从您使用的任何数据库环境中动态加载。然后很容易修改 _setFiltered() 方法以过滤 'firstName'.
以外的内容FixedDataTable 最酷的地方在于它能够浏览大型列表, 并且开发人员可以编写自己的自定义单元格渲染器,例如在列表行中的任意位置显示进度条、按钮或菜单。