我在车辆比较屏幕上有6个下拉菜单。下拉列表是使用React Modal创建的。下拉列表中的所有数据都是动态的。
加载页面后,要在前两个模式中显示的数据将获取汽车品牌,并且在模式中显示的数据将显示在下拉列表中。
当选择了汽车品牌时,将进行另一个api调用以获取该品牌中可用的模型。在第二个下拉列表中填充该数据。
由于有两个用于选择两个不同品牌的型号的下拉菜单,因此当选择一个品牌时,两个模型的下拉菜单都会更新。
如果必须为比较添加更多的汽车,如何更改代码,以便将来可以进行这项工作并使其可扩展?
Compare.js
import React, { Component } from 'react'
import {
View,
StyleSheet,
ScrollView,
SafeAreaView,
ActivityIndicator,
} from 'react-native';
import PickerModal from '../components/PickerModal';
import * as Api from "../api/app";
export default class CompareVehicles extends Component {
constructor (props) {
super(props);
this.state = {
isLoading: true,
vehicleCompany: [],
vehicleModel: [],
vehicleSubModel: [],
};
}
componentDidMount() {
this.setState({
isLoading: true,
});
this.getVehicleBrand();
}
getVehicleBrand = () => {
Api.getVehicleBrands()
.then((responseJson) => {
console.log(responseJson);
if (responseJson.success === true){
this.setState({
isLoading: false,
vehicleCompany : responseJson.data
});
} else {
alert("Error Loading Content")
}
});
};
submitBrand = async (data) => {
Api.getVehicleModel(data)
.then((responseJson) => {
console.log(responseJson);
if (responseJson.success === true){
this.setState({
vehicleModel: responseJson.data
});
} else {
alert("Error Adding Content")
}
});
};
submitModel = (data) => {
console.log(data)
};
submitVariant = (data) => {
console.log(data)
};
_renderPickerModal = (index) => {
if (this.state.vehicleSubModel.length) {
return (
<View>
<PickerModal onSubmit={this.submitBrand} type={'light-dropdown'} data={this.state.vehicleCompany}/>
<PickerModal onSubmit={this.submitModel} type={'light-dropdown'} data={this.state.vehicleModel}/>
<PickerModal onSubmit={this.submitVariant} type={'light-dropdown'} data={this.state.vehicleSubModel}/>
</View>
)
} else if(this.state.vehicleModel.length) {
return (
<View>
<PickerModal onSubmit={this.submitBrand} type={'light-dropdown'} data={this.state.vehicleCompany}/>
<PickerModal onSubmit={this.submitModel} type={'light-dropdown'} data={this.state.vehicleModel}/>
</View>
)
} else if (this.state.vehicleCompany.length) {
return (
<View>
<PickerModal onSubmit={this.submitBrand} type={'light-dropdown'} data={this.state.vehicleCompany}/>
</View>
)
}
};
render() {
if(this.state.isLoading) {
return (
<SafeAreaView style={[styles.safeArea, styles.alignJustifyCenter]}>
<ActivityIndicator/>
</SafeAreaView>
);
} else {
return (
<SafeAreaView style={styles.safeArea}>
<ScrollView
style={styles.scrollView}
scrollEventThrottle={200}
directionalLockEnabled={true}>
<View style={{flexDirection: 'row'}}>
<View style={{flex: 1}}>
{this._renderPickerModal}
</View>
<View style={{flex: 1}}>
{this._renderPickerModal}
</View>
</View>
</ScrollView>
</SafeAreaView>
);
}
}
}
const styles = StyleSheet.create({
safeArea: {
flex: 1,
backgroundColor: '#ffffff',
},
alignJustifyCenter: {
alignItems: 'center',
justifyContent: 'center'
},
scrollView: {
flex: 1,
backgroundColor: '#fff',
paddingVertical: 15,
paddingHorizontal: 20
}
});
PickerModal.js
import React, {Component} from 'react';
import { StyleSheet, Text, View, Modal, TouchableHighlight, TouchableOpacity, TouchableWithoutFeedback } from 'react-native';
import PropTypes from 'prop-types';
import Ionicons from 'react-native-vector-icons/Ionicons';
export default class PickerModal extends Component {
static propTypes = {
type: PropTypes.string.isRequired,
data: PropTypes.array.isRequired,
onSubmit: PropTypes.func.isRequired,
index: PropTypes.number
};
constructor(props) {
super(props);
this.state = {
pickerTitle: this.props.data[0].name,
pickerValue: this.props.data[0].id,
pickerDisplayed: false,
index: this.props.index
}
}
componentDidMount = () => {
console.log(this.props)
};
submit = () => {
const { pickerValue } = this.state;
const { index } = this.state;
if (pickerValue) {
this.props.onSubmit(pickerValue, index);
}
};
setPickerValue(content, index) {
this.setState({
pickerTitle: content.name,
pickerValue: content.id,
index: index
}, () => this.submit());
this.togglePicker();
}
togglePicker() {
this.setState({
pickerDisplayed: !this.state.pickerDisplayed
});
}
render() {
return (
<View style={styles.container}>
<TouchableHighlight
style={{width: '90%'}}
onPress={() => this.togglePicker()}
underlayColor='transparent'>
<View style={[styles.dropdown, this.props.type == 'dark-dropdown' ? styles.darkDropdown : styles.lightDropdown]}>
<Text style={[this.props.type == 'dark-dropdown' ? styles.darkDropdown : {}, {flex: 1}]}>{this.state.pickerTitle}</Text>
<Ionicons name={'md-arrow-dropdown'} size={25} style={[this.props.type == 'dark-dropdown' ? styles.colorWhite : {}, {marginLeft: 5, marginTop: 5}]}/>
</View>
</TouchableHighlight>
<Modal visible={this.state.pickerDisplayed} animationType={"fade"} transparent={true}>
<TouchableOpacity
activeOpacity={1}
style={{flex:1, justifyContent:'center', alignItems:'center', backgroundColor: 'rgba(0, 0, 0, 0.3)'}}
onPressOut={() => {this.togglePicker()}}>
<TouchableWithoutFeedback>
<View style={{padding: 20,
backgroundColor: '#ffffff',
bottom: 0,
left: 0,
right: 0,
alignItems: 'center',
position: 'absolute', width: '100%' }}>
{ this.props.data.map((value, index) => {
return <TouchableHighlight key={index} onPress={() => this.setPickerValue(value, this.props.index)} style={{ paddingTop: 4, paddingBottom: 4 }}>
<Text style={{fontSize: 15}}>{ value.name }</Text>
</TouchableHighlight>
})}
<TouchableHighlight onPress={() => this.togglePicker()} style={{ paddingTop: 50, paddingBottom: 20 }}>
<Text style={{color: '#999', fontSize: 20}}>Cancel</Text>
</TouchableHighlight>
</View>
</TouchableWithoutFeedback>
</TouchableOpacity>
</Modal>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
colorWhite: {
color: '#fff'
},
darkDropdown: {
backgroundColor: '#000',
borderRadius: 8,
color: '#fff'
},
lightDropdown: {
borderBottomWidth: 0.3,
borderBottomColor: '#000'
},
dropdown: {
flexDirection: 'row',
paddingHorizontal: 5,
paddingVertical: 0,
alignItems: 'center',
justifyContent: 'center',
}
});
答案 0 :(得分:0)
我相信您在做什么已经足够接近了。我将创建一个中间ContainerComponent,该容器组件应获得该品牌并与需要比较的汽车数量完全隔离。
您只需要执行以下操作:
<h2>Image Text Blocks</h2>
<p>How to place text blocks over an image:</p>
<div class="image-center">
<div class="image-container">
<img src="https://i.imgur.com/0s8kLb7.png" alt="Nature">
<div class="image-text-block">
<h3>Created with <span style="font-family:MammaGamma; color:rgb(239, 74, 74)">Photoshop</span></h3>
<p>Image: <a href="https://www.flickr.com/photos/151740882@N05/47029584231">Jane</a> by Mireille Lannoo</p>
</div>
</div>
</div>
因此,如果用户选择1、2或他们想要比较的任何数量的品牌或汽车,则主要组件仅负责管理。 PickerModalContainer将具有获取逻辑,并且根据用户选择的内容,您只需获取并更新其他PickerModals。这样,您就不必在乎其他Picker,因为他们彼此之间并不“认识”。
如果最后需要获取一些信息进行比较,则可以将函数作为props公开给PickerModalContainer,可以与下面的适当PickerModal进行对话,并从该模式中返回所需的内容。
老实说,我认为这并没有多大改变,只是一些重构。