大家好,今天我们要讲是angular2的http功能模块,这个功能模块的代码不在angular2里面,需要我们另外引入:

index.html

<script src="lib/http.dev.js"></script>

例子

这是官网的例子,包含两个程序:

  1. 英雄列表
  2. wiki关键词

第一个程序可以实现http的get请求,获取英雄列表,也可以实现http的post请求,新增英雄。

第二个程序可以实现输入关键字即时获取wiki的包含该关键字的名词列表,第一个是每输一个字符都会请求,第二个时只有停顿够300毫秒才会发出请求。两个都使用了jsonp的跨域方法。

运行方法:

在http目录或者上级目录起个服务即可:

http-server

没有则需要安装http-server:

sudo  npm install http-server -g

源代码:

https://github.com/lewis617/angular2-tutorial/tree/gh-pages/http

demo演示:

http://lewis617.github.io/angular2-tutorial/http/

In-memory web api

首先我们先来看第一个程序,英雄列表。在运行这个程序前,我们需要学习一个库,a2-in-memory-web-api

这个库的功能是可以帮助你在ng2里面虚拟api,不用你写api后台了,方便测试。顾名思义,这个库所虚拟的api在内存中,也就意味着你刷新浏览器后,所有的数据都会消失!好,让我们来学习如何使用!

第一步,你需要引入这个库:

index.html

<script src="lib/web-api.js"></script>

然后,我们要使用这个库给我们封装好的服务:

app/toh/toh.component.ts

 // in-memory web api providers
    provide(XHRBackend, { useClass: InMemoryBackendService }), // in-mem server
    provide(SEED_DATA,  { useClass: HeroData }) // in-mem server data

XHRBackend和SEED_DATA是服务里面提供的变量,我们需要设置。XHRBackend使用InMemoryBackendService来创建provider,SEED_DATA使用我们自己写的HeroData来创建provider,作用是初始化数据。我们来看HeroData的代码:

app/hero-data.ts

export class HeroData {
  createDb() {
    let heroes = [
      { "id": "1", "name": "Windstorm" },
      { "id": "2", "name": "Bombasto" },
      { "id": "3", "name": "Magneta" },
      { "id": "4", "name": "Tornado" }
    ];
    return {heroes};
  }
}

那个createDB是webapi里提供的方法用于创建虚拟的数据库。

那么什么是provider?provider就是服务,provide是ng2给我们提供的创建服务的api,这个可以参考官网,比较简单不再赘述:

https://angular.io/docs/ts/latest/api/core/provide-function.html

provider 是依赖注入中的一个概念,它决定了服务的实例化方式。

到此为止,我们的虚拟api就配置好了,我们可以在app/heroes这个url上进行get和post请求,用于获取和新增数据了。为什么是这个url?因为我们在创建数据库时候定义了这个节点:

app/hero-data.ts

 return {heroes};

你可以将其改变为heroes1或者heroes2来测试下。

使用HTTP服务

api虚拟好了,我们开始调用api,如何调用呢?我需要使用ng2给我们提供的http服务。这个服务需要额外http库文件,它不在ng2的库文件中。因为官方考虑到大家伙可能想使用别的http库吧!

我们先引入js文件:

index.html

<script src="lib/http.dev.js"></script>

然后注入服务:

app/toh/toh.component.ts

HTTP_PROVIDERS,

然后就可以在这个组建下层的服务中使用HTTP了:

app/toh/hero.service.ts

export class HeroService {
  constructor (private http: Http) {}

app/toh/hero.service.ts

this.http.get(this._heroesUrl)

app/toh/hero.service.ts

this.http.post(this._heroesUrl, body, options)

ng2的依赖注入

刚才提到了http服务的注入。我们就来聊聊“依赖注入”。

ng1里面的依赖注入被保留到ng2里面了,什么是依赖注入,为什么要用依赖注入,依赖注入和规则是什么样的?

依赖注入类似于import、require,可以将我们封装好的模块注入另一个模块,成为其依赖。

这样做有什么好处?代码复用度高,模块相互独立,管理清晰。

依赖注入的规则是什么?

  1. 注入组件指令:只能在当前组件用,当前组件的父子组件都不能用!
  2. 注入服务:可以给当前组件和其所有的子组件用!

依赖注入是一种编程模式,该模式可以让一个类从外部源中获得它的依赖,而不必亲自创建它们。

依赖注入的规则是什么?

  1. NgModule 中的服务是被注册到根注入器的。这意味着任何注册到 NgModule 上的服务都可以被整个应用访问到。
  2. 另一方面,注册到应用组件上的只在该组件及其各级子组件中可用。

有一个很有趣的问题:我们是否应该将所有服务都放在顶层?什么时候我们需要将其注入子组件中呢?

当每个组件需要独立的服务实例时候!

服务是单例模式,也就意味着我们所编写的服务只能被实例化为一个对象,如果我们将服务注入在顶层,那么我们无法享受独立的服务。比如如果你要给“英雄列表”的每一项添加编辑功能,那么“编辑”这个服务就不能放在顶层,需要放在每个英雄列表的组件上。这样才能保证每个英雄列表拥有独立的服务(比如独立的当前名称属性等)。

放在顶层的服务也很多比如,提供方法的工具库如HTTP等都可以放在顶层,我们不需要多例。还有一些用于共享数据的服务更应该放在顶层,我们需要“单例模式”来帮助我们统一共享数据!

Observable

刚才我们进行了http请求,不过我们发现,我们接着使用了map()这个方法:

app/toh/hero.service.ts

this.http.get(this._heroesUrl)         .map(res => <Hero[]> res.json().data)         .do(data => console.log(data)) // eyeball results in the console

一般情况,我们这里都会返回一个Promise,然后我们使用then来处理数据。不过这里使用了map(),很显然,这里不是Promise而是Observable!

它来自于Rx.js,可以帮助我们实现响应式编程,处理异步的另一套解决方案(promise也是一套解决方案)。

这是十分复杂的概念,不过我会多罗嗦几句,所以不用担心。首先我们先来看Observable 和Promise的区别:

  1. Observable 可以处理多个事件,Promise则通常处理一个事件
  2. Observable 可以终止,Promise则不能

我们继续解读代码,讲完你就会明白这两个区别。

this.http.get(this._heroesUrl)就返回了一个Obeservable,我们可以使用map()方法处理事件,和数组一样,你也可以使用filter。所以我们说observable可以处理多个事件。

这里的多个事件指的是什么呢?其实就是你输入的“英雄名称”,先后输入很多次,输入的名字如同流水一般进入我们程序中,我们使用observable来处理这个“流”。假如你前后就输入一次英雄名称并点击添加,那么这个流其实就一个事件。

observable定义完是不会执行的!直到你使用subscribe:

app/toh/hero-list.component.ts

this._heroService.getHeroes()
                     .subscribe(
                       heroes => this.heroes = heroes,
                       error =>  this.errorMessage = <any>error);

现在我们提到了很多observable的api,让我们总结下,后面还要补充:

  1. map():遍历流
  2. filter():过滤流
  3. do():监视流(通常打个console而已)
  4. catch():捕获异常
  5. subscribe():订阅流(即执行)

到此为止,http的第一个程序“英雄列表”就可以运行了。这节课我们先讲到这里,下节课我们继续讲解observable中更加炫酷的api用法!


教程源代码及目录

如果您觉得本博客教程帮到了您,就赏颗星吧!

https://github.com/lewis617/angular2-tutorial

angular2系列教程(八)In-memory web api、HTTP服务、依赖注入、Observable的更多相关文章

  1. 使用ASP.NET Web Api构建基于REST风格的服务实战系列教程【三】——Web Api入门

    系列导航地址http://www.cnblogs.com/fzrain/p/3490137.html 前言 经过前2节的介绍,我们已经把数据访问层搭建好了,从本章开始就是Web Api部分了.在正式开 ...

  2. 使用ASP.NET Web Api构建基于REST风格的服务实战系列教程【四】——实现模型工厂,依赖注入以及格式配置

    系列导航地址http://www.cnblogs.com/fzrain/p/3490137.html 前言 在上一篇中,我们已经初步开始使用Web Api了,但同时出现了一些很多不足之处,本章我们就着 ...

  3. 【Web API系列教程】1.2 — Web API 2中的Action Results

    前言 本节的主题是ASP.NET Web API怎样将控制器动作的返回值转换成HTTP的响应消息. Web API控制器动作能够返回下列的不论什么值: 1. void 2. HttpResponseM ...

  4. 使用Autofac在ASP.NET Web API上实现依赖注入

    在ASP.NET Web API里使用Autofac 1.通过NuGet安装Autofac.WebApi(当时安装的是Autofac 3.1.0) PM > Install-Package Au ...

  5. ASP.NET Web API中的依赖注入

    什么是依赖注入 依赖,就是一个对象需要的另一个对象,比如说,这是我们通常定义的一个用来处理数据访问的存储,让我们用一个例子来解释,首先,定义一个领域模型如下: namespace Pattern.DI ...

  6. angular2系列教程(十)两种启动方法、两个路由服务、引用类型和单例模式的妙用

    今天我们要讲的是ng2的路由系统. 例子

  7. angular2系列教程(一)hello world

    今天我们要讲的是angular2系列教程的第一篇,主要是学习angular2的运行,以及感受angular2的components以及模板语法. 例子 这个例子非常简单,是个双向数据绑定.我使用了官网 ...

  8. CRL快速开发框架系列教程八(使用CRL.Package)

    本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...

  9. Http下的各种操作类.WebApi系列~通过HttpClient来调用Web Api接口

    1.WebApi系列~通过HttpClient来调用Web Api接口 http://www.cnblogs.com/lori/p/4045413.html HttpClient使用详解(java版本 ...

  10. 黄聪:Microsoft Enterprise Library 5.0 系列教程(八) Unity Dependency Injection and Interception

    原文:黄聪:Microsoft Enterprise Library 5.0 系列教程(八) Unity Dependency Injection and Interception 依赖注入容器Uni ...

随机推荐

  1. 关于CryptoJS中md5加密以及aes加密的随笔

    最近项目中用到了各种加密,其中就包括从没有接触过得aes加密,因此从网上各种查,官方的一种说法: 高级加密标准(英语:Advanced Encryption Standard,缩写:AES),在密码学 ...

  2. .Net多线程编程—预备知识

    1 基本概念 共享内存的多核架构:一个单独的封装包内封装了多个互相连接的未处理器,且所有内核都可以访问主内存.共享内存的多核系统的一些微架构,例如内核暂停功能,超频. 内核暂停功能:当使用内核不多的时 ...

  3. C#多线程之线程池篇2

    在上一篇C#多线程之线程池篇1中,我们主要学习了如何在线程池中调用委托以及如何在线程池中执行异步操作,在这篇中,我们将学习线程池和并行度.实现取消选项的相关知识. 三.线程池和并行度 在这一小节中,我 ...

  4. Coroutine in Java - Quasar Fiber实现--转载

    转自 https://segmentfault.com/a/1190000006079389?from=groupmessage&isappinstalled=0 简介 说到协程(Corout ...

  5. 从啥也不会到可以胜任最基本的JavaWeb工作,推荐给新人的学习路线(二)

    在上一节中,主要阐述了JavaScript方面的学习路线.先列举一下我朋友的经历,他去过培训机构,说是4个月后月薪过万,虽然他现在还未达到这个指标. 培训机构一般的套路是这样:先教JavaSE,什么都 ...

  6. SSH框架和Redis的整合(2)

    5. 添加功能的实现 新建一个Action:RClasAction,实现向Redis添加课程数据,并同步到MySQL. package com.school.action; import java.u ...

  7. 使用DeviceOne实现微信小程序功能

    微信小程序即将推出,还没推出就火的不行了.基于微信这个巨大平台,小程序必然能有巨大成功.不过它并不能完全取代App,该开发App还得开发.如果我们自己想实现一个基于自己的APP包含类似微信的小程序功能 ...

  8. android Notification介绍

    如果要添加一个Notification,可以按照以下几个步骤 1:获取NotificationManager: NotificationManager m_NotificationManager=(N ...

  9. 项目持续集成环境(jenkins + SVN + maven + tomcat)

    整体流程 每次SVN上代码有变动,触发自动构建动作,并部署到服务器的tomcat上,具体流程: 1.SVN上提交代码修改 2.maven执行Goals 3.将web工程打成war包 4.关闭服务器的t ...

  10. Win10连接远程桌面时提示“您的凭据不工作”

    我遇到这个问题的时候查找网上都给出一堆高大上的解决办法, 然而我的错误实际上是用户名的问题, 很多人以为远程用户名就一定是锁屏状态下的登录名, 其实不是,跟自己设置有关,所以首先应该检查远程用户名是否 ...