ReactNavtive架構教程(4),

來源:互聯網
上載者:User

ReactNavtive架構教程(4),

原文:http://www.raywenderlich.com/99473/introducing-react-native-building-apps-javascript

 注意:所有圖片放在了百度相簿空間,如果你看不到圖片,請複製圖片URL,然後粘貼到地址欄中進行查看。


開始搜尋

為了實現搜尋概念,我們需要處理Go按鈕點擊事件,建立對應的API請求,顯示網路請求的狀態。

開啟SearchPage.js, 在constructor方法中修改state的初始化代碼:

this.state = {

  searchString: 'london',

  isLoading: false

};

isLoading 屬性用於表示查詢是否進行中。

在render方法最上面增加:

var spinner = this.state.isLoading ?

  ( <ActivityIndicatorIOS

      hidden='true'

      size='large'/> ) :

  ( <View/>);

用了一個三目運算,這是一個if語句的簡單形式。如果isLoading為true,顯示一個網路指標,否則顯示一個空的view。

在return語句中,在Image下增加:

{spinner}

在Go按鈕對應的 TouchableHighlight 標籤中增加如下屬性:

onPress={this.onSearchPressed.bind(this)}

在 SearchPage 類中新增如下方法:

_executeQuery(query) {

  console.log(query);

  this.setState({ isLoading: true });

}

 

onSearchPressed() {

  var query = urlForQueryAndPage('place_name', this.state.searchString, 1);

  this._executeQuery(query);

}

_executeQuery() 目前僅僅是在控制台中輸出一些資訊,同時設定isLoading屬性為true,剩下的功能我們留到後面完成。

注意: JavaScript類沒有訪問器,因此也就沒有私人的概念。因此我們會在方法名前加一個底線,以表示該方法視同為私人方法。

當Go按鈕被點擊, onSearchPressed() 即被調用。

在 SearchPage 類聲明之前,聲明如下實用函數:

function urlForQueryAndPage(key, value, pageNumber) {

  var data = {

      country: 'uk',

      pretty: '1',

      encoding: 'json',

      listing_type: 'buy',

      action: 'search_listings',

      page: pageNumber

  };

  data[key] = value;

 

  var querystring = Object.keys(data)

    .map(key => key + '=' + encodeURIComponent(data[key]))

    .join('&');

 

  return 'http://api.nestoria.co.uk/api?' + querystring;

};

這個函數不依賴SearchPage類,因此被定義為函數而不是方法。它首先將key\value參數以索引值對形式放到了data集合中,然後將data集合轉換成以&符分隔的“鍵=值”形式。=>文法是箭頭函數的寫法,一種建立匿名函數簡潔寫法,具體請參考

recentaddition to the JavaScript language 。

回到模擬器,按下 Cmd+R 重啟App,然後點擊‘Go’ 按鈕。你將看到網路指標開始轉動。同時控制台將輸出:


網路指標顯示,同時要請求的URL也列印出來了。拷貝並粘貼URL到Safari,查看搜尋結果。你將看到一堆JSON對象。我們將用代碼解析這些JSON對象。

注意: 這個App使用 Nestoria API 來尋找房子。尋找結果以JSON格式返回。官方文檔中列出了所有請求的URL規範及響應格式。

發送請求

開啟 SearchPage.js,在初始化狀態過程中增加一個message屬性:

this.state = {

  searchString: 'london',

  isLoading: false,

  message: ''

};

render方法中,在UI元素的最後加入:

<Text style={styles.description}>{this.state.message}</Text>

這個Text用於向使用者顯示一些文本。

在 SearchPage 類中,在 _executeQuery()方法最後加入:

fetch(query)

  .then(response => response.json())

  .then(json => this._handleResponse(json.response))

  .catch(error =>

     this.setState({

      isLoading: false,

      message: 'Something bad happened ' + error

   }));

fetch 函數在 Fetch API中定義,這個新的JavaScript規範被Firefox 39(Nightly版)以及Chrome 42(開發版)支援,它在XMLHttpRequest的基礎上進行了極大的改進。結果是非同步返回的,同時使用了 promise規範,如果response中包含有效JSON對象則將JSON對象的response成員(另一個JSON)傳到_handleResponse方法(後面實現)。

然後在 SearchPage類中增加方法:

_handleResponse(response) {

  this.setState({ isLoading: false , message: '' });

  if (response.application_response_code.substr(0, 1) === '1') {

    console.log('Properties found: ' + response.listings.length);

  } else {

    this.setState({ message: 'Location not recognized; please try again.'});

  }

}

如果查詢結果成功返回,我們重設 isLoading 屬性為false,然後列印結果集的總數。

注意: Nestoria有 不以1開頭的響應碼 這些代碼都非常有用。例如202 和 200表示返回一個推薦位置的列表。當完成這個執行個體後,你可以嘗試處理這些返回碼,並將列表提供給使用者選擇。

儲存,返回模擬器,按下Cmd+R ,然後搜尋 ‘london’你將在控制台看到一條訊息,表示搜尋到20條房子資訊。嘗試輸入一個不存在的地名,比如 ‘narnia’ 你將看到如下資訊:


展現搜尋結果

建立一個檔案: SearchResults.js, 編寫如下代碼:

'use strict';

 

var React = require('react-native');

var {

  StyleSheet,

  Image,

  View,

  TouchableHighlight,

  ListView,

  Text,

  Component

} = React;

一條requires語句和一個結構賦值。

定義一個Componet子類:

class SearchResults extends Component {

 

  constructor(props) {

    super(props);

    var dataSource = new ListView.DataSource(

      {rowHasChanged: (r1, r2) => r1.guid !== r2.guid});

    this.state = {

      dataSource: dataSource.cloneWithRows(this.props.listings)

    };

  }

 

  renderRow(rowData, sectionID, rowID) {

    return (

      <TouchableHighlight

          underlayColor='#dddddd'>

        <View>

          <Text>{rowData.title}</Text>

        </View>

      </TouchableHighlight>

    );

  }

 

  render() {

    return (

      <ListView

        dataSource={this.state.dataSource}

        renderRow={this.renderRow.bind(this)}/>

    );

  }

 

}

上述代碼中使用了一個專門的組件——ListView ——該組件非常像ITableView。通過ListView.DataSource, 我們可以向ListView提供資料。renderRow函數則用於為每個行提供UI。

在構建資料來源的時候,我們使用箭頭函數對不同的行進行識別。這個函數在ListView進行“一致化”的時候被調用,以便判斷列表中的資料是否被改變。在本例中,NestoriaAPI有一個guid屬性,剛好可以用來作為判斷的標準。

最後,加入一條模組輸出語句:

module.exports = SearchResults;

SearchPage.js 頭部,require 下方加入:

var SearchResults = require('./SearchResults');

這樣我們就可以 SearchPage 類中使用SearchResults類了。

_handleResponse 方法,將console.log 一句替換為:

this.props.navigator.push({

  title: 'Results',

  component: SearchResults,

  passProps: {listings: response.listings}

});

上述代碼將導航至SearchResults 頁面,並將請求到的列表資料傳遞給它。Push方法可以將頁面添加到導航控制器的ViewController堆棧中,同時你的導覽列上將出現一個Back按鈕,點擊它可以返回到上一頁面。

回到模擬器, 按下Cmd+R ,進行一個尋找動作。你將看到搜尋結果如下:



聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.