2015-08-02 26 views
7

Tôi đã cố gắng để hiểu làm thế nào tôi có thể quản lý để làm cho một ListView có thể nhận dữ liệu thường xuyên mới và đẩy nó vào phía trước. Với mã dưới đây, danh sách không phản ánh thay đổi một cách chính xác, thay vì có một hàng mới ở phía trên, người cuối cùng được beeing nhân đôi ..phản ứng bản địa: ListView, làm thế nào để đẩy hàng mới từ đầu

'use strict'; 

var React = require('react-native'); 
var { 
    AppRegistry, 
    StyleSheet, 
    Text, 
    View, 
    ListView, 
    TouchableHighlight, 
} = React; 

var listview = React.createClass({ 
    rows: [], 

    _rowHasChanged: function (r1, r2) { 
    // if (r1 !== r2) 
    // console.log('rowChanged', r1, r2); 
    // else 
    // console.log('row didn\'t Changed', r1, r2); 
    return r1 !== r2; 
    }, 

    getInitialState: function() { 
    return { 
     dataSource: new ListView.DataSource({rowHasChanged: this._rowHasChanged}), 
    }; 
    }, 

    componentDidMount: function() { 
    this.rows = [ 
     {id: 0, text: '0: text'}, 
     {id: 1, text: '1: text'}, 
     {id: 2, text: '2: text'}, 
     {id: 3, text: '3: text'}, 
    ]; 

    this.setState({ 
     dataSource: this.state.dataSource.cloneWithRows(this.rows), 
    }); 
    }, 

    pushTopRow: function() { 
    var id = this.rows.length; 
    this.rows.unshift({id: id, text: id + ': text'}); 

    this.setState({ 
     dataSource: this.state.dataSource.cloneWithRows(this.rows), 
    }); 
    }, 

    render: function() { 
    return (
     <View style={styles.container}> 
     <ListView 
      dataSource={this.state.dataSource} 
      renderRow={(rowData) => <Text key={rowData.id}>{rowData.text}</Text>} 
     /> 
     <TouchableHighlight 
      onPress={this.pushTopRow}> 
      <Text>PUSH TOP</Text> 
     </TouchableHighlight> 
     </View> 
    ); 
    }, 
}); 

var styles = StyleSheet.create({ 
    container: { 
    flex: 1, 
    backgroundColor: 'orange', 
    }, 
}); 

AppRegistry.registerComponent('listview',() => listview); 

sau đó tôi đã cố gắng:

pushTopRow: function() { 
    var id = this.rows.length; 
    var newRow = [{id: id, text: id + ': text'}]; 
    this.rows = newRow.concat(this.rows); 

    this.setState({ 
     dataSource: this.state.dataSource.cloneWithRows(this.rows), 
    }); 
    }, 

này thực sự hoạt động, nhưng tôi không hiểu tại sao phương pháp đầu tiên không hoạt động. Tôi đang cố gắng tìm ra những gì là thực tiễn tốt nhất để xử lý với ListView:

  • Am tôi phải sử dụng cloneWithRows với một mảng mới trong mọi trường hợp, thậm chí cho một add đơn/xóa hoạt động?
  • Có điều gì khác để thiết lập cho ListView/cơ DataSource để tác phẩm một cách chính xác với vẽ lại tối thiểu (phím, hasRowChanged so sánh cụ thể?),

loại thiếu tài liệu và exemples, nó sẽ là tuyệt vời để làm rõ nó cho tôi và bất cứ ai. cảm ơn bạn & có ngày mã tốt.

+1

Ok Tôi hiểu rằng một kiểm tra tham chiếu đã được thực hiện cho sự khác biệt thay đổi để mảng không thể chỉ đơn giản là đột biến. ** Nhưng tôi vẫn không biết làm cách nào danh sách có thể nhận biết được các thay đổi vị trí mà không làm đổ vỡ tất cả bố cục, như thêm phần tử mới lên trên hoặc xóa phần tử hiện có. ** Hiện tại, kiểm tra hàng dựa vào trên chỉ mục Array của nó, khi được chuyển ngay cả khi phần tử giống hệt nhau chỉ là một hàng bên dưới, thì nó sẽ được coi là một giá trị hoàn toàn khác và do đó vẽ lại. Đây là thảm họa cho hiệu suất:/ – Akabab

+0

Điều này có lẽ chỉ cần lưu tôi như 4 hoặc 5 giờ. CẢM ƠN BẠN RẤT NHIỀU!!! – jasonmerino

+0

lãng phí 1h cho đến khi tôi sử dụng giải pháp của bạn ... THANK YOU AS WELL – Jeremie

Trả lời

3

ListView gán khóa thành phần theo chỉ mục nguồn dữ liệu và do đó sẽ lập lại tất cả các hàng bất cứ khi nào nguồn dữ liệu được thêm vào trước. Nếu dữ liệu hàng của bạn có bất kỳ id duy nhất nào, bạn có thể tạo một ListView đã sửa đổi sử dụng nó làm khóa. Xem ví dụ PrependableListView sẽ sử dụng thuộc tính id trên dữ liệu hàng của bạn.

Lưu ý: thành phần này không được tổng quát hóa và sẽ thất bại nếu không có thuộc tính id được xác định.

Lưu ý: Tôi nhận thấy điều này không trả lời cho toàn bộ câu hỏi của bạn, chỉ là một tính đặc thù cụ thể về việc thêm vào nguồn dữ liệu.

Các vấn đề liên quan