2015-08-29 4 views
3

У меня есть проблема интеграции Firebase с React-Native. В приведенном ниже коде не создается список, как я ожидал. Мое предположение заключается в том, что message.val() не возвращает правильный формат. Когда я пытаюсь утешить журнал «сообщения» переменная возвращает как последуйтеИнтеграция ListView-native и Firebase ListView

Object {text: "hello world", user_id: 1} 

Код:

class Test extends Component { 

    constructor(props) { 
     super(props); 
     this.state = { 
      dataSource: new ListView.DataSource({ 
       rowHasChanged: (row1, row2) => row1 !== row2 
      }) 
     }; 
    } 

    componentWillMount() { 
     this.dataRef = new Firebase("https://dummy.firebaseio.com/"); 
     this.dataRef.on('child_added', function(snapshot){ 
      var messages = snapshot.val(); 
      this.setState({ 
       dataSource: this.state.dataSource.cloneWithRows(messages) 
      });  
     }.bind(this)); 
    } 

    renderRow(rowData, sectionID, rowID) { 
     console.log(this.state.dataSource); 
     return (
      <TouchableHighlight 
      underlayColor='#dddddd'> 
       <View> 
        <Text>{rowData.user_id}</Text> 
        <Text>{rowData.text}</Text> 
       </View> 
      </TouchableHighlight> 
     ) 
    } 

    render() { 
     return (
      <View> 
       <ListView 
        dataSource={this.state.dataSource} 
        renderRow={this.renderRow.bind(this)} 
        automaticallyAdjustContentInsets={false} /> 
      </View>  
     ); 
    } 

} 

ответ

2

Я не знаю, какие данные есть в базе данных Firebase, но от того, что я понимаю, вас должен получить несколько событий «on_child_added» для всех элементов, которые у вас есть, поэтому вы не должны передавать его методу «cloneWithRows». Вы должны передать весь набор данных.

В то время как документация по реагированию на родную сторону в настоящее время немного «молчала» о том, как работает источник данных ListView и что должно быть передано в «cloneWithRows», документация в коде (ListViewDataSource.js) довольно хороша, и ясно, что вы всегда должны предоставлять полный набор данных для метода cloneWithRows (аналогично сверке сверки, источник данных автоматически вычисляет разницу и только изменяет фактически измененные данные).

Кроме того, существует очень хорошая рецензия от @vjeux о том, почему они реализовали ListView так, как они это делали, включая объяснение стратегий оптимизации, которые они выбрали (отличные от UITableView от iOS).

Итак, в вашем случае вы должны аккумулировать все строки где-то в другом месте и передавать только весь массив сообщений в cloneWithRows или ретранслировать поэтапное поведение cloneWithRows и непрерывно добавлять входящие элементы в cloneWithRows, как они приведены ниже в примере (он должен быть быстрым, поэтому попробуйте).

документация копия & паста из ListViewDataSource.js:

/** 
* Provides efficient data processing and access to the 
* `ListView` component. A `ListViewDataSource` is created with functions for 
* extracting data from the input blob, and comparing elements (with default 
* implementations for convenience). The input blob can be as simple as an 
* array of strings, or an object with rows nested inside section objects. 
* 
* To update the data in the datasource, use `cloneWithRows` (or 
* `cloneWithRowsAndSections` if you care about sections). The data in the 
* data source is immutable, so you can't modify it directly. The clone methods 
* suck in the new data and compute a diff for each row so ListView knows 
* whether to re-render it or not. 
* 
* In this example, a component receives data in chunks, handled by 
* `_onDataArrived`, which concats the new data onto the old data and updates the 
* data source. We use `concat` to create a new array - mutating `this._data`, 
* e.g. with `this._data.push(newRowData)`, would be an error. `_rowHasChanged` 
* understands the shape of the row data and knows how to efficiently compare 
* it. 
* 
* ``` 
* getInitialState: function() { 
* var ds = new ListViewDataSource({rowHasChanged: this._rowHasChanged}); 
* return {ds}; 
* }, 
* _onDataArrived(newData) { 
* this._data = this._data.concat(newData); 
* this.setState({ 
*  ds: this.state.ds.cloneWithRows(this._data) 
* }); 
* } 
* ``` 
*/ 
Смежные вопросы