嘿那里:)我通过向我的SearchView添加过滤器Modal来获得以下问题
我构建了一个
SearchPage
,可以列出几个事件。这一切都很好。现在我正在尝试将filter
添加到我的SearchPage
。如果我手动设置过滤器,它可以很好地工作 - >现在我的问题:如果我尝试更改Switch的切换值,则会将其设置回root,因为未设置该值的状态
我解释过的步骤:
我正在尝试打开一个
Modal
视图,其中列出了我的所有filter
以及我可以使用true/false
设置Switch
的位置。我的想法是通过为其创建filter Settings
来获取所有JSON
:
module.exports = {
"filter":
{
"track": [
{
"id": 1,
"description": "IoT & Living tomorrow"
},
{
"id": 2,
"description": "Smart & Digital Retail"
},
{
"id": 3,
"description": "Startups, Digital Culture & Collaboration"
}
]
}
}
上面的JSON仅用于示例 - 通常它更大,并且有更多的主题而不仅仅是跟踪
现在我导入
JSON
并将其保存在var filter
。我在这里检查了数据格式是否合适 - >filter.track -> All my JSON Objects
现在我用
创建了一个班级filter Modal
import React, {Component} from 'react';
import {
ListView,
Modal,
StatusBar,
StyleSheet,
Text,
TouchableOpacity,
View,
Switch
} from 'react-native';
var filter = require('../JSON/filter');
class PopoverFilter extends Component {
constructor(props) {
super();
// ds for the menu entries
var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
this.state = {
eventTracks: ds.cloneWithRows(filter.filter.track)
}
this.show = this.show.bind(this);
}
render() {
return(
<Modal>
<ListView
style={styles.mainView}
renderRow={this.renderMenuEntries.bind(this)}
dataSource={this.state.eventTracks}/>
</Modal>
);
}
renderMenuEntries(entry) {
var switchState = entry.description;
return(
<View style={styles.switchView}>
<Text style={[styleHelper.fonts.titleSize, styles.text]}>{entry.description}</Text>
<Switch onValueChange={(value) => this.switchChanged(switchState, value)}
value={this.state.switchState}/>
</View>
);
}
switchChanged(field, value) {
var obj = {};
obj[field] = value;
this.setState(obj);
}
}
var styles = StyleSheet.create({
});
module.exports = PopoverFilter;
请忽略缺少的样式,并且模态中还有更多的对象,但对于这种情况并不重要。
最重要的是我尝试使用
renderMenuEntries
方法渲染每个Switch,并为其提供所有条目 - &gt;只是Switch的工作没有正确设置。至于我试图改变开关的值,它立即回到它的根。并没有确定任何状态。
也许我的解决方案是不可能的,我必须使每个状态都是静态的 - 但是如果我可以在以后设置动态过滤器而不更改整个代码
,这个解决方案会非常好答案 0 :(得分:1)
您描述的场景是可能的。我的代码遇到了很多问题:
在renderMenuEntries
中,您分配给<Switch />
组件的值是数据项的 description ,而不是{{1}的预期布尔值组件<Switch />
期望。此外,此值还引用了value
不存在的属性。
this.state
功能也只是使用数据项 description
使用您提供的代码示例,我从头创建了一个名为switchChanged
的新类。它不需要在此组件中使用过滤器数据,而是希望数据通过名为PopoverFilter
的组件道具进入。这将促进组件的可重用性,以接受不同的数据集。
对代码进行了大量评论,以帮助解释所演示的概念。这是filterData
类:
PopoverFilter
请注意,此import React from 'react';
import {
ListView,
Modal,
Switch,
Text,
TouchableOpacity,
View
} from 'react-native';
export default class PopoverFilter extends React.Component {
constructor (props) {
super(props);
// bind relevant handlers up front in the constructor
this.renderRow = this.renderRow.bind(this);
this.onPress = this.onPress.bind(this);
// process the incoming filter data to add a 'selected' property
// used to manage the selected state of its companion switch
this._filterData = this.processFilterData(this.props.filterData);
const ds = new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !== r2 });
this.state = {
filterDataSource: ds.cloneWithRows(this._filterData)
}
}
processFilterData (filterData) {
// don't mutate the filterData prop coming in
// use map to create a new array and use Object.assign to make
// new object instances with a new property named 'selected' initialized
// with a value of false
return filterData.map((item) => Object.assign({}, item, { selected: false }));
}
switchChanged (rowId, isSelected) {
const index = +rowId; // rowId comes in as a string so coerce to a number
const data = this._filterData;
// don't mutate this._filterData
// instead create a new array and new object instance
this._filterData = [
...data.slice(0, index), // take everything before the target index
Object.assign({}, data[index], { selected: isSelected }), // create a new object instance with updated selected property
...data.slice(index + 1) // take everything after the selected index
];
// update the listview datasource with the new data
this.setState({
filterDataSource: this.state.filterDataSource.cloneWithRows(this._filterData)
});
}
renderRow (item, sectionId, rowId) {
return(
<View>
<Text>{item.description}</Text>
<Switch
onValueChange={(value) => this.switchChanged(rowId, value)}
value={item.selected}
/>
</View>
);
}
// just a test function used to dump the current state of the _filterData
// to the console
onPress () {
console.log('data', this._filterData);
}
render () {
return (
<Modal>
<ListView
renderRow={this.renderRow}
dataSource={this.state.filterDataSource}
/>
<TouchableOpacity onPress={this.onPress}>
<Text>Get Filter Data</Text>
</TouchableOpacity>
</Modal>
);
}
}
类还会显示一个按钮,按下该按钮会将当前数据状态转储到控制台,以便您可以查看它的当前表单。
以下是如何使用该组件的示例:
PopoverFilter
答案 1 :(得分:-1)
尝试
renderMenuEntries(entry) {
var switchState = entry.description;
return(
<View style={styles.switchView}>
<Text style={[styleHelper.fonts.titleSize, styles.text]}>{entry.description}</Text>
<Switch onValueChange={(value) => this.switchChanged(switchState, value)}
value={this.state[switchState]}/>
</View>
);
}
switchChanged(field, value) {
var obj = this.state;
obj[field] = value;
this.setState({obj});
}