1

我正在尝试使用React 开发人员的这个示例来为表创建搜索过滤器。

我的表格可以静态处理来自后端的数据。我为“样本”数据取出了一个数组,以使搜索功能正常工作。但是我很难理解他们如何使用“假数据”来填充他们的表,如此处所示,而不是“只是”用我想要的测试数组填充它。

这是我的源代码。我想过滤“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
4

2 回答 2

1

你的问题出在_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),
    });
}
于 2017-02-22T14:08:26.320 回答
0

getSize() 和 getObjectAt() 只能在实现这些方法的数据对象上调用,例如 DataListWrapper 对象。

如果将纯数据数组传递给 render(),则它不提供 getSize() 和 getElementAt() 方法,并且对方法的调用将失败。

原始演示有效,因为 FakeObjectDataListStore 数据是一个对象(“FakeObjectDataListStore”),它实现了 getSize 和 getObjectAt 方法)。

所以最简单的集成是确保传入的数据是提供这些方法的对象。根据我的“examples/FilterExample”案例,我发现最简单的集成(在与许多不好的整合后)是将现有的“helpers/FakeObjectDataListStore.js”变成我自己的 helpers/ObjectDataListStore.js(或选择你的名字)从而在整个设计中保留现有的方法包装结构和尺寸参数。然后,我简单地将对“假”组件的调用替换为对我自己的非包装本地列表行数组的引用。您可以将本地数据安排为静态数据,或从您使用的任何数据库环境动态加载。然后很容易修改 _setFiltered() 方法以过滤除“firstName”之外的其他内容。

FixedDataTable 最酷的地方在于它能够浏览大型列表,并且开发人员可以编写自己的自定义单元格渲染器,例如在列表行的任何位置显示进度条、按钮或菜单。

于 2017-06-09T12:11:51.247 回答