Joh*_*ohn 5 javascript listview ios reactjs react-native
我有一个包含按钮的视图 - onPress它会打开一个显示联系人列表的模式.
任何这些联系人的onPress(pickContact函数)我想动态地添加一个新的View到_renderAddFriendTile(上面的按钮).
理想情况下,每个联系人姓名(在模态中)旁边的"添加"图标都应该更新("删除"图标),无论它们是否出现在_renderAddFriendTile视图中.
最好的方法是什么?
[更新代码]
import React, {Component} from 'react'
import {
Text,
View,
ListView,
ScrollView,
StyleSheet,
Image,
TouchableHighlight,
TextInput,
Modal,
} from 'react-native'
const friends = new ListView.DataSource({
rowHasChanged: (r1, r2) => r1 !== r2
}).cloneWithRows([
{
id: 1,
firstname: 'name01',
surname: 'surname01',
image: require('../images/friends/avatar-friend-01.png')
},
{
id: 2,
firstname: 'name02',
surname: 'surname02',
image: require('../images/friends/avatar-friend-02.png')
},
{
id: 3,
firstname: 'name03',
surname: 'surname03',
image: require('../images/friends/avatar-friend-03.png')
},
{
id: 4,
firstname: 'name04',
surname: 'surname04',
image: require('../images/friends/avatar-friend-04.png')
},
])
class AppView extends Component {
state = {
isModalVisible: false,
contactPicked: [],
isFriendAdded: false,
}
setModalVisible = visible => {
this.setState({isModalVisible: visible})
}
pickContact = (friend) => {
if(this.state.contactPicked.indexOf(friend) < 0){
this.setState({
contactPicked: [ ...this.state.contactPicked, friend ],
})
}
if(this.state.contactPicked.indexOf(friend) >= 0){
this.setState({isFriendAdded: true})
}
}
_renderAddFriendTile = () => {
return(
<View style={{flex: 1}}>
<View style={[styles.step, styles.stepAddFriend]}>
<TouchableHighlight style={styles.addFriendButtonContainer} onPress={() => {this.setModalVisible(true)}}>
<View style={styles.addFriendButton}>
<Text style={styles.addFriendButtonText}>Add a friend</Text>
</View>
</TouchableHighlight>
</View>
</View>
)
}
render(){
return (
<ScrollView style={styles.container}>
<Modal
animationType={'fade'}
transparent={true}
visible={this.state.isModalVisible}
>
<View style={styles.addFriendModalContainer}>
<View style={styles.addFriendModal}>
<TouchableHighlight onPress={() => {this.setModalVisible(false)}}>
<View>
<Text style={{textAlign:'right'}}>Close</Text>
</View>
</TouchableHighlight>
<ListView
dataSource={friends}
renderRow={(friend) => {
return (
<TouchableHighlight onPress={() => {this.pickContact()}}>
<View style={[styles.row, styles.friendRow]}>
<Image source={friend.image} style={styles.friendIcon}></Image>
<Text style={styles.name}>{friend.firstname} </Text>
<Text style={styles.name}>{friend.surname}</Text>
<View style={styles.pickContainer}>
<View style={styles.pickWrapper}>
<View style={this.state.isFriendAdded ? [styles.buttonActive,styles.buttonSmall]: [styles.buttonInactive,styles.buttonSmall]}>
<Image source={this.state.isFriendAdded ? require('../images/button-active.png'): require('../images/button-inactive.png')} style={styles.buttonIcon}></Image>
</View>
</View>
</View>
</View>
</TouchableHighlight>
)
}}
/>
</View>
</View>
</Modal>
{this._renderAddFriendTile()}
</ScrollView>
)
}
}
export default AppView
Run Code Online (Sandbox Code Playgroud)
由于您需要动态更新某些内容,因此您需要利用本地状态对数据进行建模.(另外你没有像Redux那样使用状态库管理)
state = {
isModalVisible: false,
contactPicked: null,
}
Run Code Online (Sandbox Code Playgroud)
您的pickContact函数需要listView中的朋友数据,因此您需要使用所选行调用它:
<TouchableHighlight onPress={() => {this.pickContact(friend)}}>
Run Code Online (Sandbox Code Playgroud)
然后在您的pickContact函数内部,使用新contactsPicked数据模型更新UI
pickContact = (friend) => {
this.setState({
contactPicked: friend,
});
}
Run Code Online (Sandbox Code Playgroud)
这将使您的组件重新渲染,并且您可以在内部放置一些逻辑_renderAddFriendTile以呈现一些额外的UI(视图,文本...),因为this.state.contactPicked您可以使用以下内容:
_renderAddFriendTile = () => {
return(
<View style={{flex: 1}}>
{this.state.contactPicked && (
<View>
<Text>{contactPicked.firstName}<Text>
</View>
)}
<View style={[styles.step, styles.stepAddFriend]}>
<TouchableHighlight style={styles.addFriendButtonContainer} onPress={() => {this.setModalVisible(true)}}>
<View style={styles.addFriendButton}>
<Text style={styles.addFriendButtonText}>Add a friend</Text>
</View>
</TouchableHighlight>
</View>
</View>
)
}
Run Code Online (Sandbox Code Playgroud)
请注意,您现在保持状态为所选联系人的firstName,因此第2点应该易于解决.在renderRowListView 内部,渲染一个不同的Icon iffriend.firstname === this.state.contactPicked.firstname
注意:不要依赖firstname进行此类检查,因为您可能会重复检查并且会失败.最佳解决方案是为列表模型提供id每个联系人的唯一属性,并使用该id属性检查上述逻辑.
附注
该部分{this.state.contactPicked && (<View><Text>Some text</Text></View)}使用条件渲染.&&作为if if的行为如果this.state.contactPicked是真实的,它将呈现视图,否则它将不呈现任何内容(falsy和null值被反应解释为"无需呈现").
当然,如果要动态渲染多个项目,则状态模型应该是一个数组,即contactsPicked最初为空.每次选择联系人时,都会向阵列添加新的联系人对象.然后在里面_renderAddFriendTile你可以使用map来动态渲染多个组件.我想你不需要一个ListView,除非你想要一个单独的可滚动列表.
_renderAddFriendTile = () => {
return(
<View style={{flex: 1}}>
{this.state.contactsPicked.length && (
<View>
{this.state.contactsPicked.map(contact => (
<Text>{contact.firstName}</Text>
)}
</View>
)}
<View style={[styles.step, styles.stepAddFriend]}>
<TouchableHighlight style={styles.addFriendButtonContainer} onPress={() => {this.setModalVisible(true)}}>
<View style={styles.addFriendButton}>
<Text style={styles.addFriendButtonText}>Add a friend</Text>
</View>
</TouchableHighlight>
</View>
</View>
)
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7728 次 |
| 最近记录: |