-- 第十一课:获取数据,Observable和Promise
虽然很多移动应用是完全自容的(计算器,音板,待办列表,照片应用,手电筒应用),但很多应用靠着从外部源拉取数据。Facebook需要为新闻种子拉取数据,Instagram的最新图片,天气原因的最新天气预报等等。 这个部分我们将涵盖如何拉取外部数据到你的Ionic应用。在进入具体学习从外部服务获取数据之前,我得先涵盖一点我们将要做什么的知识。
映射与过滤数据
map映射和filter过滤功能非常强大,允许你对数组做很多事情。这些不是神奇的ES6或者Angular 2功能,他们是JavaScript的一部分。 简单起见,映射针对数组的每个数据,对他运行一些函数,这些函数可能会改变数据的值,然后将他放到一个新的数组中。他将一个数组的每个值映射到一个新的数组。为了给你一个直观的理解,以下范例展示他为何有用,假定你有一个文件名的数字,这样:
然后你就可以将这些值的完整路径映射到一个新的数组:
代码是这样的:
我们给map提供了一个函数用于返回修改的值。我们提供的函数会接受每一个值作为传入参数。
过滤和映射很像,但是和映射到一个新的数组不同,他只会添加匹配指定标准的值到新的数组。我们就用之前的例如,但是这次我们想要返回所有包含.png文件的数组。代码如下:
如果我们同时还要完整路径的话,我们可以将filter和map链接起来用:
这样,我们就先过滤出我们不需要的结果,然后给他们映射完整路径到一个新的数组。结果将是一个包含了完整路径的两个.png文件的数组。这个就先停止这里,当我们学习获取数据的范例的时候,为什么值得花费这么多精力去解释他将会很明了。
Observables 和 Promises
如果你用过Ionic 1或者有很强劲的JavaScript背景的话,那么你可能熟悉Promises,但是熟悉Observables的人非常少。Observable核心新功能之一,包括Angular2(RxJS提供),所以理解他是什么他们和Promise的区别非常重要(他们看起来和表现起来都很像)。 在进入Observable之前,我们先具体了解一下Promise是什么。当我们编写异步(意思是代码不是顺序执行的)代码的时候,Promise就介入了。在使用HTTP请求数据的时候,我们需要等待数据返回,由于这个返回可能需要等待1-10秒钟,我们不可能在这个等待阶段同步停止整个应用。我们需要保持应用中等待的同时一直运行接受新的用户输入,当最终得到请求返回的时候,我们再对他进行处理。 Promise就是用来对付这种情况的,如果你熟悉回调函数,那么它就是相同的理念,只是更好一些。假设我们有一个方法名为getFromSlowServer() 返回一个promise,我们这样去使用:
利用Http从服务端拉取数据
那么你稍微整理一下就可以很轻松的阅读JSON反馈。但是我们要怎样将他带入到我们的Ionic 2应用中呢? 答案是使用Angular 2提供的Http服务,他允许你发起HTTP请求。如果你不知道HTTP请求是什么,基本上浏览器每次加载任何东西(文档,图片,文件等等)的时候,他就会发起HTTP请求。所以我们可以发起一个页面的HTTP请求,然后可以返回一些JSON数据给我们的应用使用。 首先我们需要设置Http服务,我们来看一个测试页面导入并注入了这个服务:
由于咱们注入了Http服务,通过public修饰符我们可以使用this.http来自类里面使用。同时注意,我们从RxJS库里面导入了map操作符。之前讲过map是数组默认提供的函数 -- 所以为什么我们需要从一个奇怪的库里面导入呢?因为Http服务并不会返回一个数组,他返回的是Observable。RxJS库为Observable提供了map函数,所以我们的先进行导入。 现在我们看一下向reddit URL发起请求的代码:
调用的第一部分给咱们返回一个Observable。然后我们使用map函数,在其中将JSON文本通过json()函数将他对象化。这样我们就能更好的去用了。 重要:记住,Http请求是异步的。意思是你的代码只会在拉取到数据之后才会向前执行,这里过程可能是几毫秒到10秒,甚至不会返回。所以应用得预先做好应对。如果你运行如下代码:
你可以看到帖子输出到控制台,因为subscribe函数里面的所有事物都会在数据返回的时候运行。 返回我们的例子,在我们映射完响应之后我们链了一个subscribe调用在其中我们可以使用通过流(Observable)提交来的数据。之前说过Observable有用因为我们可以一直监听不同的值...但是为什么在这里用他?Http调用只会返回一次结果,为什么不用Promise替代Observable来避免混淆大家视听? 此处偏爱Observable而不是Promise的原因是Observable可以做Promise做的所有,在场景外技术上更好,可以做Promise做不到的其他事情。例如我们可以设置一个定时器interval来每5秒或者10秒发起Http请求,我们可以简单的设置debouncing保证请求不会太频繁的发起(预防向服务器大量发起请求),如果在旧请求结果返回之前Observable可以取消‘在发’请求等等。 以下是Giflists应用中的代码:
在这里subredditControl是一个Observable。用户使用应用里输入就可以控制他的值。subscribe里面的代码只会在1秒(debounceTime)内不在变动的情况和新值和之前的值不一样的情况下执行。这个例子可以很清晰的表达subscribe帮你处理了多少奇怪的东西。 如果看到上面的例子你想‘哇... Ionic 2太难了,我要回去找Ionic 1!’,最好不要!这是举证Observable的一个高级范例,Ionic 2输入处理和双向数据绑定和Ionic 1一样简单。 Observable是一个大的主题,还有成吨的东西需要去学习。如果你不知道啥情况的话也不要被吓到。在制作Ionic应用的时候最好对Obserable有一个比较好的认识,但是对于Ionic来讲,他只是理解就好(虽然他比较重要但是你不是经常用到)你同样可以过的很好。
从自己的服务器拉取数据
我们知道了如何使用JSON反馈从类似reddit提供的服务器拉取数据,但是如果你想拉取自己的数据呢?你要怎样才能设置你自己的JSON反馈呢? 详细深入如何设置你自己的API超出了本课程的范围,但是我会给你指出大概。基本上:
1.在Ionic应用里面发起请求到你的服务器URL
2.从你的服务器拉取数据,服务器语言随你喜欢
3.以JSON格式将需求的数据打印到页面
我会带你通过PHP实现一个简单的API,-- 你可以用你自己喜欢的语言 —— 这样你就可以输出JSON到浏览器:
2.获取数据。本案例中我通过查询MySQL,当然数据来源可以是不同的方式:
```php
$mysqli = new mysqli("localhost", "username", "password", "database");
$query = "SELECT * FROM table";
$dbresult = $mysqli->query($query);
while($row = $dbresult->fetch_array(MYSQLI_ASSOC)){ $data[] = array( 'id' => $row['id'], 'name' => $row['name'] ); }
if($dbresult){ $result = "{'success':true, 'data':" . json_encode($data) . "}"; } else { $result = "{'success':false}"; }
之前讲过,可以使用任何服务端语言,可以使用任何存储机制。只要能够以JSON格式获得你要的数据,然后输出到浏览器就可以了。
这个给了你一个很合理的概观:如何使用Ionic 2 和Http服务来获取远程数据。这里的代码第一眼看来语法和概念可能有些花俏,但是当你进入基础的时候会发现你需要知道的不是太多。你的数据可能更复杂,你也许想要对他进行更神奇的操作,或者以不同的方式在显示,但是基本原理还是一致的。
译者:这两章翻译得有点烂,因为心情焦躁
Last updated