根据数据库数据的存在添加条件
add a condition according to the presence of a database data
我有一个要在其中添加图像的列表。
基本上我的代码工作正常,不幸的是我使用的 API 数据库发生了变化......我数据库中的一些产品没有图像所以当我调用有问题的行时它给我一个错误......
所以,我想创建一个条件:如果数据库中有相关产品的图像,我希望显示它
Image source={{uri: URL + item.photo.1.url}}
不然我要它是一个预设的标志。
<图片来源={require('../../../assets/images/logo.png')}
我是这样做的:
<ListItem.Content style={{flexDirection: 'row', justifyContent: 'space-between'}}>
{item.photo !== null && item.photo > 0 ? (
<Image
source={{uri: URL + item.photo._1_.url}}
style={{ width: 25, height: 25}}/>
) : (
<Image
source={require('../../../assets/images/logo.png')}
style={{ width: 25, height: 25}}
/>
)};
<ListItem.Title style={{width: '65%', fontSize: 16}}>{ ( item.name.length > 20 ) ? item.name.substring(0, 20) + ' ...' : item.name}</ListItem.Title>
<ListItem.Subtitle style={{ color: '#F78400', position: "absolute", bottom: 0, right: 0 }}>{item.cost}{i18n.t("products.money")}</ListItem.Subtitle>
</ListItem.Content>
但是我有两个错误:
undefined is not an object (evaluating 'item.photo.1.url')
[Unhandled promise rejection: Error: Text strings must be rendered
within a component.]
向您展示数据的外观:
以及该屏幕的完整代码:
export default class Products extends Component {
constructor(props) {
super(props);
this.state = {
productId: (props.route.params && props.route.params.productId ? props.route.params.productId : -1),
listData: '',
selectedId: '',
setSelectedId: '',
currentPage: 1,
loadMoreVisible: true,
loadMoreVisibleAtEnd: false,
displayArray: []
}
};
initListData = async () => {
let list = await getProducts(1);
if (list) {
this.setState({
displayArray: list,
loadMoreVisible: (list.length >= 10 ? true : false),
currentPage: 2
});
}
};
setNewData = async (page) => {
let list = await getProducts(parseInt(page));
if (list) {
this.setState({
displayArray: this.state.displayArray.concat(list),
loadMoreVisible: (list.length >= 10 ? true : false),
loadMoreVisibleAtEnd: false,
currentPage: parseInt(page)+1
});
}
};
loadMore() {
this.setNewData(this.state.currentPage);
}
displayBtnLoadMore() {
this.setState({
loadMoreVisibleAtEnd: true
});
}
async componentDidMount() {
this.initListData();
}
render() {
//console.log('url', URL );
//console.log('displayArray', this.state.displayArray);
//console.log('name', this.state.displayArray.name);
//console.log('photo', this.state.displayArray.photo);
return (
<View style={{flex: 1}}>
{this.state.displayArray !== null && this.state.displayArray.length > 0 ? (
<View style={{ flex: 1}}>
<SafeAreaView>
<FlatList
data={this.state.displayArray}
extraData={this.selectedId}
style={{width: '98%'}}
onEndReached={() => this.displayBtnLoadMore()}
renderItem={({item, index, separators })=>
<View style={{flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center'}}>
<ListItem
style={{width:'100%'}}
containerStyle= {{backgroundColor: index % 2 === 0 ? '#fde3a7' : '#FFF'}}
bottomDivider
onPress={() => this.props.navigation.navigate('ProductDetails', {productId:parseInt(item.id)})}>
<ListItem.Content style={{flexDirection: 'row', justifyContent: 'space-between'}}>
{item.photo !== null && item.photo > 0 ? (
<Image
source={{uri: URL + item.photo._1_.url}}
style={{ width: 25, height: 25}}/>
) : (
<Image
source={require('../../../assets/images/logo.png')}
style={{ width: 25, height: 25}}
/>
)};
<ListItem.Title style={{width: '65%', fontSize: 16}}>{ ( item.name.length > 20 ) ? item.name.substring(0, 20) + ' ...' : item.name}</ListItem.Title>
<ListItem.Subtitle style={{ color: '#F78400', position: "absolute", bottom: 0, right: 0 }}>{item.cost}{i18n.t("products.money")}</ListItem.Subtitle>
</ListItem.Content>
</ListItem>
</View>
}
keyExtractor={(item,index)=>index.toString()}
style={{width:"100%"}}
/>
{this.state.loadMoreVisible === true && this.state.loadMoreVisibleAtEnd === true ? (
<Button title=" + " onPress={()=>{this.loadMore()}}></Button>
) : null
}
<View style={styles.container}>
<Text>{"\n"}</Text>
<TouchableOpacity
style={styles.touchable2}
onPress={() => this.props.navigation.goBack()}
>
<View style={styles.container}>
<Button
color="#F78400"
title= 'Back'
onPress={() => this.props.navigation.goBack()}>BACK
</Button>
</View>
</TouchableOpacity>
</View>
<Text>{"\n\n"}</Text>
</SafeAreaView>
</View>
) : (
<View style={styles.container}>
<Text>{"\n\n" + (this.state.displayArray === null ? i18n.t("products.searching") : i18n.t("products.nodata")) + "\n\n\n"}</Text>
<Button
color="#F78400"
title= 'Back'
onPress={() => this.props.navigation.goBack()}>BACK
</Button>
</View>
)}
</View>
);
};
}
我对如何去做有点迷茫,所以如果你有任何线索可以帮助我,任何线索都会很棒。非常感谢
本次测试:
item.photo !== null && item.photo > 0
不会return如您所愿。原因是当没有照片时,属性 被设置为空字符串。所以该测试的第一部分应该是:
item.photo !== ''
接下来,当有照片时,photo
属性是一个物体。所以第二部分应该是:
item.photo.constructor === 'Object'
但是,如果有不止一张照片,那将是复杂的。您的代码建议您只想要第一张照片(不管有多少张)。
因此,如果您按照我的建议进行更改,它应该会按预期工作。
如果我是你,我会完全跳过第一个测试,因为现在没有必要,因为第二个测试涵盖了这两种情况。我建议只这样做:
{item.photo.constructor === 'Object' ? (
我有一个要在其中添加图像的列表。 基本上我的代码工作正常,不幸的是我使用的 API 数据库发生了变化......我数据库中的一些产品没有图像所以当我调用有问题的行时它给我一个错误...... 所以,我想创建一个条件:如果数据库中有相关产品的图像,我希望显示它
Image source={{uri: URL + item.photo.1.url}}
不然我要它是一个预设的标志。 <图片来源={require('../../../assets/images/logo.png')}
我是这样做的:
<ListItem.Content style={{flexDirection: 'row', justifyContent: 'space-between'}}>
{item.photo !== null && item.photo > 0 ? (
<Image
source={{uri: URL + item.photo._1_.url}}
style={{ width: 25, height: 25}}/>
) : (
<Image
source={require('../../../assets/images/logo.png')}
style={{ width: 25, height: 25}}
/>
)};
<ListItem.Title style={{width: '65%', fontSize: 16}}>{ ( item.name.length > 20 ) ? item.name.substring(0, 20) + ' ...' : item.name}</ListItem.Title>
<ListItem.Subtitle style={{ color: '#F78400', position: "absolute", bottom: 0, right: 0 }}>{item.cost}{i18n.t("products.money")}</ListItem.Subtitle>
</ListItem.Content>
但是我有两个错误:
undefined is not an object (evaluating 'item.photo.1.url')
[Unhandled promise rejection: Error: Text strings must be rendered within a component.]
向您展示数据的外观:
以及该屏幕的完整代码:
export default class Products extends Component {
constructor(props) {
super(props);
this.state = {
productId: (props.route.params && props.route.params.productId ? props.route.params.productId : -1),
listData: '',
selectedId: '',
setSelectedId: '',
currentPage: 1,
loadMoreVisible: true,
loadMoreVisibleAtEnd: false,
displayArray: []
}
};
initListData = async () => {
let list = await getProducts(1);
if (list) {
this.setState({
displayArray: list,
loadMoreVisible: (list.length >= 10 ? true : false),
currentPage: 2
});
}
};
setNewData = async (page) => {
let list = await getProducts(parseInt(page));
if (list) {
this.setState({
displayArray: this.state.displayArray.concat(list),
loadMoreVisible: (list.length >= 10 ? true : false),
loadMoreVisibleAtEnd: false,
currentPage: parseInt(page)+1
});
}
};
loadMore() {
this.setNewData(this.state.currentPage);
}
displayBtnLoadMore() {
this.setState({
loadMoreVisibleAtEnd: true
});
}
async componentDidMount() {
this.initListData();
}
render() {
//console.log('url', URL );
//console.log('displayArray', this.state.displayArray);
//console.log('name', this.state.displayArray.name);
//console.log('photo', this.state.displayArray.photo);
return (
<View style={{flex: 1}}>
{this.state.displayArray !== null && this.state.displayArray.length > 0 ? (
<View style={{ flex: 1}}>
<SafeAreaView>
<FlatList
data={this.state.displayArray}
extraData={this.selectedId}
style={{width: '98%'}}
onEndReached={() => this.displayBtnLoadMore()}
renderItem={({item, index, separators })=>
<View style={{flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center'}}>
<ListItem
style={{width:'100%'}}
containerStyle= {{backgroundColor: index % 2 === 0 ? '#fde3a7' : '#FFF'}}
bottomDivider
onPress={() => this.props.navigation.navigate('ProductDetails', {productId:parseInt(item.id)})}>
<ListItem.Content style={{flexDirection: 'row', justifyContent: 'space-between'}}>
{item.photo !== null && item.photo > 0 ? (
<Image
source={{uri: URL + item.photo._1_.url}}
style={{ width: 25, height: 25}}/>
) : (
<Image
source={require('../../../assets/images/logo.png')}
style={{ width: 25, height: 25}}
/>
)};
<ListItem.Title style={{width: '65%', fontSize: 16}}>{ ( item.name.length > 20 ) ? item.name.substring(0, 20) + ' ...' : item.name}</ListItem.Title>
<ListItem.Subtitle style={{ color: '#F78400', position: "absolute", bottom: 0, right: 0 }}>{item.cost}{i18n.t("products.money")}</ListItem.Subtitle>
</ListItem.Content>
</ListItem>
</View>
}
keyExtractor={(item,index)=>index.toString()}
style={{width:"100%"}}
/>
{this.state.loadMoreVisible === true && this.state.loadMoreVisibleAtEnd === true ? (
<Button title=" + " onPress={()=>{this.loadMore()}}></Button>
) : null
}
<View style={styles.container}>
<Text>{"\n"}</Text>
<TouchableOpacity
style={styles.touchable2}
onPress={() => this.props.navigation.goBack()}
>
<View style={styles.container}>
<Button
color="#F78400"
title= 'Back'
onPress={() => this.props.navigation.goBack()}>BACK
</Button>
</View>
</TouchableOpacity>
</View>
<Text>{"\n\n"}</Text>
</SafeAreaView>
</View>
) : (
<View style={styles.container}>
<Text>{"\n\n" + (this.state.displayArray === null ? i18n.t("products.searching") : i18n.t("products.nodata")) + "\n\n\n"}</Text>
<Button
color="#F78400"
title= 'Back'
onPress={() => this.props.navigation.goBack()}>BACK
</Button>
</View>
)}
</View>
);
};
}
我对如何去做有点迷茫,所以如果你有任何线索可以帮助我,任何线索都会很棒。非常感谢
本次测试:
item.photo !== null && item.photo > 0
不会return如您所愿。原因是当没有照片时,属性 被设置为空字符串。所以该测试的第一部分应该是:
item.photo !== ''
接下来,当有照片时,photo
属性是一个物体。所以第二部分应该是:
item.photo.constructor === 'Object'
但是,如果有不止一张照片,那将是复杂的。您的代码建议您只想要第一张照片(不管有多少张)。
因此,如果您按照我的建议进行更改,它应该会按预期工作。
如果我是你,我会完全跳过第一个测试,因为现在没有必要,因为第二个测试涵盖了这两种情况。我建议只这样做:
{item.photo.constructor === 'Object' ? (