2017-03-07 70 views
0

我试图更新数据源和我已经检查了以下网址反应本地的ListView数据源没有更新

https://github.com/facebook/react-native/issues/4104 https://github.com/mobxjs/mobx/issues/569

我累了创建新阵列,然后更新,但我不确定如何更新数据源。

关于更改复选框,我正在更新对象并将其分配给数据源,但复选框未更新。

下面是我试过的代码。

构造

constructor() { 
      super(); 
      const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2}); 

      this.state = { 
       modalVisible: false, 
       todoText:'', 
       todoListArray:[], 
       dataSource: ds 

      }; 

     } 

列表视图

<ListView 
dataSource={this.state.dataSource} 
     renderRow={this.generateRow.bind(this)} 
     /> 

generateRow=(rowData, sectionID, rowID, highlightRow) => { 

    return (
      <View style={styles.listItem}> 
       <CheckBox 
        label='' 
        checked={rowData.isCompleted} 
        onChange={() => {this.changeisCompleted(this,rowID)}} 
       /> 
       <Text style={styles.listItemText}>{rowData.text}</Text> 

      </View> 

     ); 

    } 

/*When Checkbox is clicked*/ 
    changeisCompleted=(rowData,rowId)=>{ 

     var newDs = []; 
     newDs = this.state.todoListArray.slice(); 
     newDs[rowId].isCompleted =!newDs[rowId].isCompleted; 
     alert(JSON.stringify(newDs)); 
     this.setState({ 
      dataSource: this.state.dataSource.cloneWithRows(newDs) 
     }) 


    } 

/*adding new item to listView*/ 
    addTodo =() => { 
       var todoObj={ 
       "text":this.state.todoText, 
       "isCompleted":false 
       } 
       this.state.todoListArray.push(todoObj); 
       this.closeModal(); 
       this.setState({todoText: ''}); 
       this.setState({ 
        dataSource: this.state.dataSource.cloneWithRows(this.state.todoListArray) 
       }) 
      } 

添加整个文件:

/** 
    * Sample React Native App 
    * https://github.com/facebook/react-native 
    * @flow 
    */ 

import React, { Component } from 'react'; 
import { 
    AppRegistry, 
    StyleSheet, 
    Text, 
    View, 
    ToolbarAndroid, 
    Modal, 
    Button, 
    TextInput, 
    Image, 
    ListView, 
    TouchableHighlight 

} from 'react-native'; 

import CheckBox from 'react-native-checkbox'; 

{/*import AddToDoModal from './src/components/AddTodoModal.js';*/} 


export default class FirstReactNativeApp extends Component { 

    constructor() { 
     super(); 
     const ds = new ListView.DataSource({rowHasChanged: (row1, row2) => row1 !== row2}); 

     this.state = { 
      modalVisible: false, 
      todoText:'', 
      todoListArray:[], 
      dataSource: ds, 

     }; 

    } 
componentDidMount =() => function() { 

} 

openModal =() => { 
    this.setState({modalVisible: true}); 

} 
closeModal =() => { 
    this.setState({modalVisible: false}); 
} 
setModalVisible=(visible) =>{ 
    this.setState({modalVisible: visible}); 
} 
changeisCompleted=(rowData,rowId)=>{ 

    var newDs = []; 
    newDs = this.state.todoListArray.slice(); 
    newDs[rowId].isCompleted =!newDs[rowId].isCompleted; 
    newDs[rowId].text ="Changed"; 
    alert(JSON.stringify(newDs)); 
    //this.state.todoListArray=newDs; 
    //alert("listArray=="+JSON.stringify(this.state.todoListArray)) 
    this.setState({ 
     todoListArray:newDs, 
     dataSource: this.state.dataSource.cloneWithRows(newDs) 
    }) 


} 
addTodo =() => { 
    var todoObj={ 
    "text":this.state.todoText, 
    "isCompleted":false 
    } 
    this.state.todoListArray.push(todoObj); 
    this.closeModal(); 
    this.setState({todoText: ''}); 
    this.setState({ 
     dataSource: this.state.dataSource.cloneWithRows(this.state.todoListArray) 
    }) 
} 
generateRow=(rowData, sectionID, rowID, highlightRow) => { 


    return (
     <View style={styles.listItem}> 
      <CheckBox 
       label='' 
       checked={rowData.isCompleted} 
       onChange={() => {this.changeisCompleted(this,rowID)}} 
      /> 
      <Text style={styles.listItemText}>{rowData.text}</Text> 

     </View> 

    ); 

} 

render() { 
    return (
    <View> 
      <ToolbarAndroid 
      style={styles.toolbar} 
      title="ToDo List" 
      actions={[{title: 'Add', icon: require('./img/add.png'), show: 'always'}]} 
      onActionSelected={this.openModal} 
      /> 

      <ListView 
      dataSource={this.state.dataSource} 
      renderRow={this.generateRow.bind(this)} 
      /> 



      <Modal 
      animationType={"none"} 
      transparent={false} 
      visible={this.state.modalVisible} 
      onRequestClose={() => {alert("Modal has been closed.")}} > 

       <View style={styles.container}> 
       <View style={styles.modalContent}> 

         {/*this is icon button*/} 
         <TouchableHighlight style={{justifyContent:'flex-end',flexDirection:'row'}} onPress={this.closeModal}> 
          <Image 
           style={styles.closeButton} 
           source={require('./img/close.png')} 
          /> 
         </TouchableHighlight> 
         <Text style={{textAlign:'center',marginBottom:30}}>Add New ToDo</Text> 
         <TextInput 
          style={{height: 40, borderColor: 'gray', borderWidth: 1,marginBottom:10}} 
          placeholder='Enter ToDo' 
          onChangeText={(todoText) => this.setState({todoText})} 
          value={this.state.todoText} 
         /> 
        <Button 
          onPress={()=> {this.addTodo()}} 
          title='Add ToDo' 
          color='#1e90ff'/> 


        </View> 
       </View> 
      </Modal> 

    </View> 
); 
} 

} 

const styles = StyleSheet.create({ 
    container: { 
    flex: 1, 
    justifyContent: 'center', 
    alignItems: 'center', 
    backgroundColor: '#000000', 
    opacity:0.8 
    }, 
    welcome: { 
    fontSize: 20, 
    textAlign: 'center', 
    margin: 10, 
    }, 
    instructions: { 
    textAlign: 'center', 
    color: '#333333', 
    marginBottom: 5, 
    }, 
    toolbar: { 
    height:55, 
    backgroundColor: '#1e90ff', 
    }, 
    modal: { 
    height:50, 
    marginVertical:22, 
    }, 
    modalContent: { 
    backgroundColor: '#ffffff', 
    height:300, 
    width:300, 
    borderRadius:3, 
    paddingVertical:10, 
    paddingHorizontal:20, 

    }, 
    closeButton: { 
    height:30, 
    width:30, 
    }, 
    listItem: { 
    backgroundColor: '#ffffff', 
    paddingLeft:10, 
    height:50, 
    borderBottomWidth:1, 
    borderColor: '#000000', 
    flex:1, 
    flexDirection:'row', 
    alignItems:'center', 
    }, 
    listItemText: { 

    fontSize:20, 

    } 
}); 

AppRegistry.registerComponent('FirstReactNativeApp',() => FirstReactNativeApp); 
+0

嗨示例可能会解决你的问题试试看https://hellokoding.com/todo-app-with-react-native-realm/ –

+0

http://stackoverflow.com/questions/31738671/react-native-updating- list-view-datasource – vinayr

+0

我已经尝试了这两个链接,请检查更新后的代码并提示其中的任何错误。 –

回答

0

大量的阅读,并改变列表视图现在更新。 据this

更改DS声明:

this.ds = new ListView.DataSource({rowHasChanged: (row1, row2) => row1 !== row2}); 

因此改变了我的changeisComplete方法

changeisCompleted=(rowData,rowId)=>{ 

      var newDs = []; 
      newDs = this.state.todoListArray.slice(); 
      newDs[rowId].isCompleted =!newDs[rowId].isCompleted; 


      this.setState({ 
        dataSource: this.ds.cloneWithRows(this.state.todoListArray), 
        todoListArray:newDs 
       }) 


      } 

我不知道这是否是这样做的正确的方式,但无论如何它的作品,现在复选框正在变化

谢谢

0

你有两个问题。首先,您将数据源设置为克隆结果。只需使用{this.state.dataSource}:

dataSource={this.state.dataSource.cloneWithRows(this.state.todoListArray)} 

因为您正在设置DS结果并且未链接数据源。此外,您不需要状态中的双数据(数组和数据源)。

而第二个也是最重要的,你并没有真正设定状态。只有在构造函数中,你可以像这样设置它:this.state。

之后,你才可以设置它像这样:

所以经过
this.setState({dataSource: this.state.dataSource.cloneWithRows(updatedArray)}); 
+0

已更新我的代码。请检查addToDo方法是否将新对象添加到listview中,但changeisCompleted方法什么也不做。 –