2016-06-21 63 views
2

我目前正在学习react-native并陷入ListView问题。我想从TextInput中搜索ListView中的数据,我希望结果也在ListView中。ListView中的搜索数据反应原生

这里是我到目前为止已经完成:

var PageOne = React.createClass({ 
 
    getInitialState:function(){ 
 
    return{ 
 
     dataSource: new ListView.DataSource({ 
 
     rowHasChanged: (row1, row2) => row1 !== row2, 
 
     }), 
 
     loaded: false, 
 
     colorProps: { 
 
     titleColor: 'white', 
 
     }, 
 
     searchText:"", 
 
    } 
 
    }, 
 

 
    componentDidMount() { 
 
    this.fetchData(); 
 
    }, 
 

 
    fetchData() { 
 
    fetch(REQUEST_URL) 
 
     .then((response) => response.json()) 
 
     .then((responseData) => { 
 
     this.setState({ 
 
      dataSource: this.state.dataSource.cloneWithRows(responseData.movies), 
 
      loaded: true, 
 
     }); 
 
     }) 
 
     .done(); 
 
    }, 
 

 
    setSearchText(action){ 
 
    let searchText = event.nativeEvent.text; 
 
    this.setState({searchText}); 
 

 
    /* 
 
    * 
 
    * 
 
    */ 
 

 
    }, 
 

 
    render() { 
 
    return (
 
     <View style={{ flex: 1 }}> 
 
     <ToolbarAndroid 
 
      title="Movies" 
 
      {...this.state.colorProps} 
 
      style={{height:40, backgroundColor:'blue'}} 
 
      /> 
 
     <TextInput 
 
      placeholder="Search movies......." 
 
      value={this.state.searchText} 
 
      onChange={this.setSearchText.bind(this)} /> 
 
     <ListView 
 
     dataSource={this.state.dataSource} 
 
     renderRow={this.renderMovie} 
 
     style={styles.listView} 
 
     /> 
 
     </View> 
 
    ); 
 
    }, 
 

 
    renderMovie(movie) { 
 
    return (
 
    <TouchableOpacity onPress={this._handlePressList.bind(this, movie)}> 
 
     <View style={styles.container}> 
 
     <Image 
 
      source={{uri: movie.posters.thumbnail}} 
 
      style={styles.thumbnail} 
 
     /> 
 
     <View style={styles.rightContainer}> 
 
      <Text style={styles.title}>{movie.title}</Text> 
 
      <Text style={styles.year}>{movie.year}</Text> 
 
     </View> 
 
     </View> 
 
    </TouchableOpacity> 
 
    ); 
 
    },

我应该接下来做什么?请帮忙。谢谢:)

更新!阅读urbancvek答案后,我在setSearchText()方法中添加的功能是这样的:

setSearchText(event){ 
 
    const searchText = event.nativeEvent.text; 
 
    
 
    moviesLength = this.state.movies.length; 
 
    aMovie = this.state.movies; 
 

 
    const filteredMovies = this.state.movies.filter(checkTitle); 
 
    console.log("movies: " + JSON.stringify(filteredMovies)); 
 

 
    function checkTitle() { 
 
     for(i=0;i<moviesLength;i++){ 
 
      if(aMovie[i].title === searchText){ 
 
      console.log("found: " + aMovie[i].title); 
 
      return aMovie[i]; 
 
      } 
 
     } 
 
    } 
 
    
 
    this.setState({ 
 
     searchText, 
 
     dataSource: this.state.dataSource.cloneWithRows(filteredMovies), 
 
    }); 
 
    },

但它总是告诉我所有的电影,而不是过滤之一。有任何想法吗?谢谢

+0

您的'checkTitle()'过滤器函数在匹配时返回_all_电影。你不需要迭代'aMovie'数组,而只需修改'checkTitle(movie)'为'return movie.title.startsWith(searchText);' – Bataleon

回答

1

在你fetchData方法你应该保存responseData陈述了。每次搜索字段发生变化时,您都会与这些数据交互。

fetchData() { 
    fetch(REQUEST_URL) 
     .then((response) => response.json()) 
     .then((responseData) => { 
     this.setState({ 
      dataSource: this.state.dataSource.cloneWithRows(responseData.movies), 
      movies: responseData.movies, 
      loaded: true, 
     }); 
     }).done(); 
}, 

现在您的setSearchText()方法,你应该包括一些过滤功能,可将发现你从在fetchData()保存状态电影想要的电影。

setSearchText(action){ 
    const searchText = event.nativeEvent.text; 
    const filteredMovies = this.state.movies.filter(/* awesome filter function */); 

    this.setState({ 
     searchText, 
     dataSource: this.state.dataSource.cloneWithRows(filteredMovies); 
    }); 
}, 

每次你想更新ListView,你必须更新它的dataSource。只有这样,ListView组件才能意识到它所显示的数据已经改变。

希望我帮了忙。

+0

我在问题中添加了我的工作更新。 – sptra

+0

它解决了!我在'setSearchText()'方法中用obj.indexOf(searchText)添加了一个函数,它工作。非常感谢你@urbancvek :) – sptra

0

在列表视图中搜索数据基本上只是在链表或数组中搜索它,只需在数据源或数据blob中进行输入和搜索就可以了。无论你喜欢什么,都可以使用线性搜索或二分搜索。