Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/search/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Search 使用React Native进行搜索和筛选_Search_Reactjs_React Native_Filtering_React Native Listview - Fatal编程技术网

Search 使用React Native进行搜索和筛选

Search 使用React Native进行搜索和筛选,search,reactjs,react-native,filtering,react-native-listview,Search,Reactjs,React Native,Filtering,React Native Listview,我试图用react native实现一个搜索和过滤栏,但不太确定如何使用DataSource对象。数据采用JSON格式,应执行以下操作: 基于查询字符串对提供的JSON进行全文搜索 基于标记的筛选,使用作为标记提供的标记 下面是一个关于的非常简单的例子 如何在react native中实现搜索和筛选功能 import React, {Component} from 'react'; import { AppRegistry, View, ListView, Text, TextInput,

我试图用react native实现一个搜索和过滤栏,但不太确定如何使用DataSource对象。数据采用JSON格式,应执行以下操作:

  • 基于查询字符串对提供的JSON进行全文搜索
  • 基于标记的筛选,使用作为标记提供的标记
下面是一个关于的非常简单的例子

如何在react native中实现搜索和筛选功能

import React, {Component} from 'react';
import { AppRegistry, View, ListView, Text, TextInput, StyleSheet, TouchableOpacity } from 'react-native';

const FILTERS = [
        {
          tag: "clever", active: false
        }, {
          tag: "scary", active: false
        }, {
          tag: "friendly", active: false
        }, {
          tag: "obedient", active: false
        }
      ];

const FIELDS = [
        {
          title:"Dog",
          subtitle: "Bulldog",
          tags: [ { tag: "clever" }, { tag: "scary" } ]
        }, {
          title:"Cat",
          subtitle:"Persian cat",
          tags: [ { tag: "friendly" }, { tag: "obedient" } ]
        }, {
          title:"Dog",
          subtitle:"Poodle",
          tags: [ { tag: "obedient" } ]
        }
      ];

class SampleApp extends Component {

  constructor(props) {
    super(props);
    var ds = new ListView.DataSource({
        rowHasChanged: (row1, row2) => row1 !== row2,
    });
    var ds2 = new ListView.DataSource({
        rowHasChanged: (row1, row2) => row1.active !== row2.active,
    });
    this.state = {
      dataSource: ds.cloneWithRows(FIELDS),
      dataSource2: ds2.cloneWithRows(FILTERS),
      filters: FILTERS,
    };
  }

  renderFilter(filter) {
    return (
        <TouchableOpacity onPress={this.handleClick.bind(this, filter)}>
            <Text style={{fontSize: 24, backgroundColor:(filter.active)?'red':'grey', margin:5}}>{filter.tag}</Text>
      </TouchableOpacity>
    ); 
  }

  renderField(field) {
    return (
      <View style={{flexDirection:'column', borderWidth: 3, borderColor: 'yellow'}}>
        <Text style={{fontSize: 24}}>{field.title}</Text>
        <Text style={{fontSize: 24}}>{field.subtitle}</Text>
        {field.tags.map((tagField) => {
          return (
            <View style={{backgroundColor:'blue'}}>
              <Text style={{fontSize: 24}}>{tagField.tag}</Text>
            </View>
          );
        })}
      </View>
    );
  }

  handleClick(filter) {
    const newFilters = this.state.filters.map(a => {
      let copyA = {...a};
      if (copyA.tag === filter.tag) {
        copyA.active = !filter.active;
      }
      return copyA;
    });
    this.setState({
      dataSource2: this.state.dataSource2.cloneWithRows(newFilters),
      filters: newFilters
    }); 
  }

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

  render() {
    return (
      <View>
        <TextInput
                    style={styles.searchBar}
                    value={this.state.searchText}
                    onChange={this.setSearchText.bind(this)}
                    placeholder="Search" />
        <ListView
          style={{flexDirection:'row', flex:1, flexWrap:'wrap'}}
          horizontal={true}
          dataSource={this.state.dataSource2}
          renderRow={this.renderFilter.bind(this)}
        />
        <ListView
          dataSource={this.state.dataSource}
          renderRow={this.renderField.bind(this)}
        />
      </View>
    );
  }
}

const styles = StyleSheet.create({
  searchBar: {
    marginTop: 30,
    fontSize: 40,
    height: 50,
    flex: .1,
    borderWidth: 3,
    borderColor: 'red',
  },
});

AppRegistry.registerComponent('SampleApp', () => SampleApp);
import React,{Component}来自'React';
从“react native”导入{AppRegistry、View、ListView、Text、TextInput、样式表、TouchableOpacity};
常数过滤器=[
{
标签:“聪明”,活动:错误
}, {
标签:“可怕”,活动:错误
}, {
标签:“友好”,活动:假
}, {
标签:“服从”,活动:假
}
];
常量字段=[
{
标题:“狗”,
副标题:“斗牛犬”,
标签:[{tag:“聪明”},{tag:“可怕”}]
}, {
标题:“猫”,
字幕:“波斯猫”,
标签:[{tag:“友好”},{tag:“顺从”}]
}, {
标题:“狗”,
副标题:“狮子狗”,
标签:[{tag:“顺从”}]
}
];
类SampleApp扩展组件{
建造师(道具){
超级(道具);
var ds=new ListView.DataSource({
行已更改:(行1,行2)=>行1!==行2,
});
var ds2=新建ListView.DataSource({
行已更改:(行1,行2)=>row1.active!==row2.active,
});
此.state={
数据源:ds.cloneWithRows(字段),
数据源2:ds2.cloneWithRows(过滤器),
过滤器:过滤器,
};
}
渲染过滤器(过滤器){
返回(
{filter.tag}
); 
}
渲染场(场){
返回(
{field.title}
{field.subtitle}
{field.tags.map((tagField)=>{
返回(
{tagField.tag}
);
})}
);
}
把手舔(过滤器){
const newFilters=this.state.filters.map(a=>{
让copyA={…a};
if(copyA.tag==filter.tag){
copyA.active=!filter.active;
}
返回copyA;
});
这是我的国家({
dataSource2:this.state.dataSource2.cloneWithRows(newFilters),
过滤器:新过滤器
}); 
}
setSearchText(事件){
让searchText=event.nativeEvent.text;
this.setState({searchText});
}
render(){
返回(
);
}
}
const styles=StyleSheet.create({
搜索栏:{
玛金托普:30,
尺寸:40,
身高:50,
弹性体:.1,
边框宽度:3,
边框颜色:“红色”,
},
});
AppRegistry.registerComponent('SampleApp',()=>SampleApp);

这是一个解决方案,它在一个功能中完成搜索和过滤。欢迎就如何改进提出建议

import React,{Component}来自'React';
从“react native”导入{AppRegistry、View、ListView、Text、TextInput、样式表、TouchableOpacity};
常数过滤器=[
{
标签:“聪明”,活动:错误
}, {
标签:“可怕”,活动:错误
}, {
标签:“友好”,活动:假
}, {
标签:“服从”,活动:假
}
];
常量字段=[
{
标题:“狗”,
副标题:“斗牛犬”,
标签:[“聪明”、“可怕”],
主动:对,
}, {
标题:“猫”,
字幕:“波斯猫”,
标签:[“友好”、“顺从”],
主动:对,
}, {
标题:“狗”,
副标题:“狮子狗”,
标签:[“服从”],
主动:对,
}
];
类SampleApp扩展组件{
建造师(道具){
超级(道具);
var ds=new ListView.DataSource({
行已更改:(行1,行2)=>行1!==行2,
});
var ds2=新建ListView.DataSource({
行已更改:(行1,行2)=>row1.active!==row2.active,
});
此.state={
数据源:ds.cloneWithRows(字段),
数据源2:ds2.cloneWithRows(过滤器),
过滤器:过滤器,
};
}
渲染过滤器(过滤器){
返回(
{filter.tag}
); 
}
渲染场(场){
变量字段元素=
{field.title}
{field.subtitle}
{field.tags.map((tagField)=>{
返回(
{tagField}
);
})}
如果(field.active==true){
返回字段元素;
}否则{
返回null;
}
}
handleFilterClick(过滤器){
const newFilters=this.state.filters.map(f=>{
设copyF={…f};
if(copyF.tag==filter.tag){
copyF.active=!filter.active;
}
返回复印件;
});
这是我的国家({
dataSource2:this.state.dataSource2.cloneWithRows(newFilters),
过滤器:新过滤器
});
this.searchAndFilter();
}
setSearchText(事件){
让searchText=event.nativeEvent.text;
这是我的国家({
搜索文本,
});
this.searchAndFilter();
}
searchAndFilter(){
//获取过滤标签
var filteredTags=[];
this.state.filters.forEach((filter)=>{
if(filter.active){
filteredTags.push(filter.tag);
}
});
const searchResults=FIELDS.map(f=>{
设copyF={…f};
//滤器
if(filteredTags.length!==intersect\u safe(filteredTags,copyF.tags).length){
copyF.active=false;
返回复印件;
}
//搜寻
如果(!this.state.searchText | | this.state.searchText==“”){
copyF.active=true;
}else if(copyF.title.indexOf(this.state.searchText)!=-1){
copyF.active=true;
}else if(copyF.subtitle.indexOf(this.state.searchText)!=-1){
copyF.active=true;
}否则{
复制
import React, {Component} from 'react';
import { AppRegistry, View, ListView, Text, TextInput, StyleSheet, TouchableOpacity } from 'react-native';

const FILTERS = [
        {
          tag: "clever", active: false
        }, {
          tag: "scary", active: false
        }, {
          tag: "friendly", active: false
        }, {
          tag: "obedient", active: false
        }
      ];

const FIELDS = [
        {
          title:"Dog",
          subtitle: "Bulldog",
          tags: [ "clever", "scary" ],
          active: true,
        }, {
          title:"Cat",
          subtitle:"Persian cat",
          tags: [ "friendly", "obedient" ],
          active: true,
        }, {
          title:"Dog",
          subtitle:"Poodle",
          tags: [ "obedient" ],
          active: true,
        }
      ];

class SampleApp extends Component {

  constructor(props) {
    super(props);
    var ds = new ListView.DataSource({
        rowHasChanged: (row1, row2) => row1 !== row2,
    });
    var ds2 = new ListView.DataSource({
        rowHasChanged: (row1, row2) => row1.active !== row2.active,
    });
    this.state = {
      dataSource: ds.cloneWithRows(FIELDS),
      dataSource2: ds2.cloneWithRows(FILTERS),
      filters: FILTERS,
    };
  }

  renderFilter(filter) {
    return (
        <TouchableOpacity onPress={this.handleFilterClick.bind(this, filter)}>
            <Text style={{fontSize: 24, backgroundColor:(filter.active)?'red':'grey', margin:5}}>{filter.tag}</Text>
      </TouchableOpacity>
    ); 
  }

  renderField(field) {

    var fieldElement = <View style={{flexDirection:'column', borderWidth: 3, borderColor: 'yellow'}}>
        <Text style={{fontSize: 24}}>{field.title}</Text>
        <Text style={{fontSize: 24}}>{field.subtitle}</Text>
        {field.tags.map((tagField) => {
          return (
            <View style={{backgroundColor:'blue'}}>
              <Text style={{fontSize: 24}}>{tagField}</Text>
            </View>
          );
        })}
      </View>

    if (field.active == true) {
      return fieldElement;
    } else {
        return null; 
    }
  }

  handleFilterClick(filter) {
    const newFilters = this.state.filters.map(f => {
      let copyF = {...f};
      if (copyF.tag === filter.tag) {
        copyF.active = !filter.active;
      }
      return copyF;
    });
    this.setState({
      dataSource2: this.state.dataSource2.cloneWithRows(newFilters),
      filters: newFilters
    });
    this.searchAndFilter();
  }

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

  searchAndFilter() {
    //Get filtered tags
    var filteredTags = [];

    this.state.filters.forEach((filter) => {
      if (filter.active) {
        filteredTags.push(filter.tag);
      }
    });

    const searchResults = FIELDS.map(f => {
      let copyF = {...f};

      //Filter
      if (filteredTags.length !== intersect_safe(filteredTags, copyF.tags).length) {
        copyF.active = false;
        return copyF;
      }

      //Search
      if (!this.state.searchText || this.state.searchText == '') {
        copyF.active = true;
      } else if (copyF.title.indexOf(this.state.searchText) != -1) {
        copyF.active = true;
      } else if (copyF.subtitle.indexOf(this.state.searchText) != -1) {
        copyF.active = true;
      } else {
        copyF.active = false;
      }
      return copyF;
    });

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

  render() {
    return (
      <View>
        <TextInput
                    style={styles.searchBar}
                    value={this.state.searchText}
                    onChange={this.setSearchText.bind(this)}
                    placeholder="Search" />
        <ListView
          style={{flexDirection:'row', flex:1, flexWrap:'wrap'}}
          horizontal={true}
          dataSource={this.state.dataSource2}
          renderRow={this.renderFilter.bind(this)}
        />
        <ListView
          dataSource={this.state.dataSource}
          renderRow={this.renderField.bind(this)}
        />
      </View>
    );
  }
}

function intersect_safe(a, b)
{
  var ai=0, bi=0;
  var result = [];

  while( ai < a.length && bi < b.length )
  {
     if      (a[ai] < b[bi] ){ ai++; }
     else if (a[ai] > b[bi] ){ bi++; }
     else /* they're equal */
     {
       result.push(a[ai]);
       ai++;
       bi++;
     }
  }

  return result;
}

const styles = StyleSheet.create({
  searchBar: {
    marginTop: 30,
    fontSize: 40,
    height: 50,
    flex: .1,
    borderWidth: 3,
    borderColor: 'red',
  },
});

AppRegistry.registerComponent('SampleApp', () => SampleApp);