码迷,mamicode.com
首页 > 其他好文 > 详细

ReactNavtive框架教程(4)

时间:2015-07-19 11:54:20      阅读:114      评论:0      收藏:0      [点我收藏+]

标签:

原文: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 ,进行一个查找动作。你将看到搜索结果如下:

技术分享


ReactNavtive框架教程(4)

标签:

原文地址:http://blog.csdn.net/kmyhy/article/details/46953355

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!