2017-02-22 6 views
1

React開発者がthis exampleを使用してテーブルの検索フィルタを作成しようとしています。React fixed-data-table:未知のTypeError:this._dataList.getSizeは関数ではありません

バックエンドのデータを静的に使用してテーブルを正常に動作させました。私は検索機能を動作させるために "サンプル"データ用の配列を取り出しました。しかし、私は難しい時を迎えて、テーブルを ""にするために "擬似データ"を使う方法を頭に入れています。

私のソースコードです。 Facebookの例(簡単のために)のように、 "firstName"列をフィルタリングしたいと思います。このエラーは、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 
+0

申し訳ありませんが、それは間違っています。まず第一に、オブジェクトをクラスに格納できる状態にオブジェクトを格納することは本当に悪いことです。あなたの州に格納する必要があります:dataListLoaded。データリストがロードされると、コンポーネントを再レンダリングするためにsetState(dataListLoaded:true)を作成する必要があります。 – Kornflexx

+0

十分に公正で、私は一般的にReactとフロントエンドのものに比較的新しいです。あなたが言及したことのコード例を提供できるなら、私はそれを試してみたいと思います。 – cbll

+0

es6と反応して良いコードを見つけるには、これを見てください:https://github.com/ryanmcdermott/clean-code-javascriptとmaterial-uiのような良いライブラリのソースコード – Kornflexx

答えて

1

問題は_onFilterChangeメソッドにあります。

あなたはこれをやっている:

var size = this._dataList.getSize(); 

this._dataListは単なる配列である、のgetSize()は、そのオブジェクトには存在しない理由です。

私はあなたがこれを行う必要がありますmisundertandingていないよ場合:同じループ内で起こっます

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), 
    }); 
} 
0

getSize()およびgetObjectAt()は、DataListWrapperオブジェクトなど、これらのメソッドを実装するデータオブジェクトに対してのみ呼び出すことができます。

render()にプレーンデータ配列を渡すと、getSize()メソッドとgetElementAt()メソッドが提供されず、メソッドの呼び出しが失敗します。

FakeObjectDataListStoreデータがgetSizeメソッドとgetObjectAtメソッドを実装するオブジェクト( 'FakeObjectDataListStore')であるため、元のデモが機能します。

もっとも簡単な統合は、渡されたデータがこれらのメソッドを提供するオブジェクトであることを確認することです。私の場合、 'examples/FilterExample'に基づいて、既存の 'helpers/FakeObjectDataListStore.js'を自分のヘルパー/ ObjectDataListStore.js(またはあなたの名前を選んだ人)に変えることが最も簡単な統合(多くの悪いものと苦労した後)既存のメソッドラッピング構造とサイズパラメータを設計全体に保持します。私は単に、「偽の」コンポーネントへの呼び出しを、自分のラップされていないリスト行のローカル配列への参照に置き換えました。ローカルデータを静的に並べ替えることも、使用するデータベース環境から動的にロードすることもできます。 _setFiltered()メソッドを変更して、 'firstName'以外のものをフィルタするのは簡単でした。

FixedDataTableのクールなことは、大きいリストをブラウズする能力である であり、開発者はリスト行のどこにでもプログレスバー、ボタン、またはメニューを表示するなど、独自のカスタムセルレンダラーを作成できることです。

関連する問題