上一篇:Angular2入门系列教程6-路由(二)-使用多层级路由并在在路由中传递复杂参数


感觉这篇不是很好写,因为涉及到网络请求,如果采用真实的网络请求,这个例子大家拿到手估计还要自己写一个web api来提供调用;好在Angular2提供了本地模拟的api,可以供我们编写方便;但是,真实使用的情况往往与本地模拟有一些差别,会存在跨域等一系列问题;这些不在本篇文章的讲解范围之内,如果在.net下遇到跨域问题可以直接私信我。

Angular的http模块并不是Angular2的核心模块,你并不一定要使用它;我们有很多替代方案,比如你可以使用jQuery的ajax,又或是自己编写网络请求;这都不重要,你不学习这一节的内容并不会影响你使用Angular

假设你已经跟上了我们的进度,那,就开始吧

首先我们得要建立一个模拟的api文件,在我们的data目录下,内容如下

  1. import { InMemoryDbService } from 'angular-in-memory-web-api';
  2. export class InMemoryDataService implements InMemoryDbService {
  3. createDb() {
  4. let blogs=[
  5. { id:1,title:"号外号外?奥巴马要下台啦",profile:"唐纳德·特朗普,第45任美国总统,1946年6月14日生于美国纽约,政治家、商人、作家、主持人。特朗普1968年从宾夕法尼亚大学"},
  6. { id:2,title:"什么?奥巴马要下台啦?",profile:"除房地产外,特朗普将投资范围延伸到其他行业,包括开设赌场、高尔夫球场等。他还涉足娱乐界,是美国真人秀《名人学徒》等电视节目的主持人"},
  7. { id:3,title:"号外号外?川普要上台了",profile:"特朗普在过去20年间分别支持过共和党和民主党各主要总统竞选者。2015年6月,特朗普以共和党竞选者身份正式参加2016年美国总统选举。此前,特朗普没有担任过公共职务"},
  8. { id:4,title:"啥?我大四川人也要当美国总统了?",profile:"2016年11月9日,美国大选计票结果显示:共和党候选人唐纳德·特朗普已获得了276张选举人票,超过270张选举人票的获胜标准,当选美国第45任总统"},
  9. { id:5,title:"mdzz,一群麻瓜,统统查杀",profile:"1946年6月14日,特朗普在纽约市出生,排行老二,上有一个姐姐,下有两个弟弟、一个妹妹。由于祖父英年早逝,父亲"},
  10. { id:6,title:"首推龙文,必须出具",profile:"父母亲友的爱心呵护下,特朗普自幼即满腹自信,活力四射,无法静下来用功读书。13岁那年,父母只好送他去“纽约军事学校”求学,冀望军校的严格训练能帮助他力争上游。在军校就读期间,特朗普"}
  11. ]
  12. return {blogs};
  13. }
  14. }

这里有些朋友会遇到  找不到 angular-in-memory-web-api 这个模块的错误,我们在package.json里面添加这段代码,"angular-in-memory-web-api": "~0.1.13",

位置在"devDependencies"下面,然后在命令行npm install一下

ok,这里就是我们的新的数据来源,那么要如何使用呢?

先到app.module.ts中配置,这里贴出全部代码吧

  1. import { BrowserModule } from '@angular/platform-browser';
  2. import { NgModule } from '@angular/core';
  3. import { FormsModule } from '@angular/forms';
  4. import { HttpModule } from '@angular/http';
  5. import { AppRoutingModule } from './app.routing';
  6. import { ArticleDetailRoutingModule } from './articledetail.routing';
  7. //in memery
  8. import { InMemoryWebApiModule } from 'angular-in-memory-web-api';
  9. import { InMemoryDataService } from './data/in-memery-data.service'
  10.  
  11. import {BlogService} from './data/blog.service';
  12. import {CommentService} from './data/comment.service';
  13.  
  14. import { AppComponent } from './app.component';
  15. import { ArticleComponent } from './article/article.component';
  16. import { ArticledetailComponent } from './articledetail/articledetail.component';
  17. import { CommentComponent } from './comment/comment.component';
  18.  
  19. @NgModule({
  20. declarations: [
  21. AppComponent,
  22. ArticleComponent,
  23. ArticledetailComponent,
  24. CommentComponent
  25.  
  26. ],
  27. imports: [
  28. BrowserModule,
  29. FormsModule,
  30. HttpModule,
  31. ArticleDetailRoutingModule,
  32. InMemoryWebApiModule.forRoot(InMemoryDataService),//in memery
  33. AppRoutingModule
  34.  
  35. ],
  36. providers: [BlogService,CommentService],
  37. bootstrap: [AppComponent]
  38. })
  39. export class AppModule { }

有备注的话我就不解释什么了,就是模块导入而已

接下来,在我们的blog.service.ts里面使用http去获取这些数据

要使用Angular2的http服务,首先要导入它

import {Http,Response ,Headers} from "@angular/http";

Http就是http请求模块,至于Response的话是返回值类型,Headers是请求头的配置,这个我们在之后会用得到;

必须说明一下的是,Angular2的get http请求的返回值都是Observable类型的,这是。。。Observable(可观察对象)是一个管理异步数据流的强力方式。。很多概念,这个以后再讲吧。我们这里通过rxjs将它转为一个Promise对象,Promise相对来说好理解一些,在一个Promise有了结果时,它承诺会回调我们,我们请求一个异步服务去做点什么,并且给它一个回调函数。 当Promise的工作一旦完成,它就会调用我们的回调函数,并通过参数把工作结果或者错误信息传给我们;详细信息的话可以自行搜索;

好,现在来改造我们的blog.service.ts

  1. import { Injectable } from '@angular/core';
  2. import {Http,Response ,Headers} from "@angular/http";
  3.  
  4. import 'rxjs/Rx';
  5.  
  6. import { Blog,BLOGS } from './blog';
  7.  
  8. @Injectable()
  9. export class BlogService {
  10. private apiUrl="app/blogs";
  11. private headers = new Headers({'Content-Type': 'application/json'});
  12.  
  13. constructor(private http:Http){}
  14.  
  15. getBlogs():Promise<Blog[]> {
  16. return this.http.get(this.apiUrl)
  17. .toPromise()
  18. .then(r=> r.json().data as Blog[]); //BLOGS;
  19. }
  20. getSelectedBlog(id:number):Promise<Blog>
  21. {
  22. let blog=new Blog();
  23. return this.getBlogs().then(blogs=>blogs.find(x=>x.id==id));
  24. }
  25.  
  26. create(title: string):Promise<Blog> {
  27. return this.http
  28. .post(this.apiUrl, JSON.stringify({title: title}), {headers: this.headers})
  29. .toPromise()
  30. .then(res => res.json().data);
  31.  
  32. }
  33.  
  34. editBlog(blog:Blog)
  35. {
  36. let editBlog= BLOGS.find(x=>x.id==blog.id);
  37. editBlog=blog;
  38. }
  39. addBlog(blog:Blog):string
  40. {
  41. var maxId=0;
  42. BLOGS.forEach(x=>{
  43. if(x.id>maxId)
  44. maxId=x.id;
  45. });
  46. blog.id=maxId;
  47. if(blog.title.length==0)
  48. {
  49. return "title 不能未空";
  50. }
  51. else{
  52. BLOGS.push(blog);
  53. return "success";
  54. }
  55. }
  56. }

要将结果转为Promise,我们需要导入rxjs,代码如上

其他我们在构造函数中注入了http模块,然后使用了它,我们这里就简单得使用了get和post两种方式,当然,Angualr2提供了put以及delete,用法都一样,这里就不多举例了;上面的post方法使用了JSON.stirngify来处理我们的参数,实际情况中,我们可以直接将一个Object类型传过去就行了,类似与下面的代码

  1. create(blog: Blog):Promise<Blog> {
  2. return this.http
  3. .post(this.apiUrl, blog, {headers: this.headers})
  4. .toPromise()
  5. .then(res => res.json().data);
  6.  
  7. }

Angular会帮我们处理这些数据

Angular默认的请求方式是 header {'Content-Type': 'application/json'};如果需要其他请求类型,需要自己指定;但是,Angular2最终也会将请求的参数处理为一个Json,至于你的后台要用什么去接收,那就是你的事情了。

本篇文章中的本地模拟api的地址,以及操作方法为什么能成功你并不用关心,这只是用作例子而已,实际开发中并不会这样,如果你有真实的api,那就请使用真实的api吧。

由于我们将返回类型修改为了Promise,那么我们以前的组件里面的代码也需要修改,首先是

article.component.ts

  1. import { Component } from '@angular/core';
  2. import {BLOGS,Blog} from '../data/blog';
  3. import {BlogService} from './../data/blog.service';
  4.  
  5. import {Observable} from 'rxjs';
  6.  
  7. @Component({
  8. selector: 'ngarticle',
  9. templateUrl: './article.component.html',
  10. styleUrls:['./article.component.css']
  11. })
  12.  
  13. export class ArticleComponent {
  14. blogList:Blog[];
  15. selectedBlog:Blog;
  16. editStr:string;
  17. constructor(private bService:BlogService)
  18. {
  19. bService.getBlogs().then(x=>{this.blogList=x});
  20. }
  21. selectBlog(id:number)
  22. {
  23. this.bService.getSelectedBlog(id).then(blog=>{this.selectedBlog=blog;console.log(blog);});
  24. }
  25. doAdd()
  26. {
  27. if(this.editStr.length>0)
  28. {
  29. this.bService.create(this.editStr)
  30. .then(x=>{
  31. this.blogList.push(x);this.editStr=""
  32. });
  33. }
  34. }
  35. }

这里我们额外处理了一个新增文章的操作,那,我们到html页面添加一个按钮

  1. <div class="article">
  2. <ul class="articleList">
  3. <li *ngFor="let blog of blogList" [routerLink]="['/articledetail',blog.id]" >
  4. <a>
  5. {{blog.id}}:{{blog.title}}
  6. </a>
  7. </li>
  8. </ul>
  9. <div>
  10. </div>
  11. <div class="container">
  12. <div class="row">
  13. <button class="btn" (click)="doAdd()">新增文章</button>
  14. <input type="text" class="input" [(ngModel)]="editStr">
  15. </div>
  16. </div>

接下来我们处理下articleDetail.component.ts就行了

由于只修改了ngOnInit,这里就不贴那么多代码了

  1. ngOnInit() {
  2. let id=this.aRoute.params
  3. .switchMap((params: Params) =>this.bService.getSelectedBlog(+params['id']))
  4. .subscribe(x=>this.blog=x)
  5. }

到此,我们的网络请求一块就可以正常工作了

由于Angualr2的http涉及到一些额外的处理方式,包括Promise和Observable,这使得很多人刚开始会很不适应;但是Angular并不强制你使用这些,你可以使用自己的请求方式;但是使用rxjs能带来很强的流处理方式,这些都需要深入学习之后才能体会到,如果你的项目对异步等要求没那么强,你可以直接使用promise或者直接用ajax都是可行的,具体看你的项目需求。之后可能会带来关于RxJs的教程,可能

更新ing。。。


项目已经放到了gitbub上,地址 https://github.com/SeeSharply/LearnAngular

本文章的提交 https://github.com/SeeSharply/LearnAngular/tree/b6396476023bb388b93bfd6f922374f790a71786

Angular2入门系列教程7-HTTP(一)-使用Angular2自带的http进行网络请求的更多相关文章

  1. Angular2入门系列教程1-使用Angular-cli搭建Angular2开发环境

    一直在学Angular2,百忙之中抽点时间来写个简单的教程. 2016年是前端飞速发展的一年,前端越来越形成了(web component)组件化的编程模式:以前Jquery通吃一切的田园时代一去不复 ...

  2. Angular2入门系列教程6-路由(二)-使用多层级路由并在在路由中传递复杂参数

    上一篇:Angular2入门系列教程5-路由(一)-使用简单的路由并在在路由中传递参数 之前介绍了简单的路由以及传参,这篇文章我们将要学习复杂一些的路由以及传递其他附加参数.一个好的路由系统可以使我们 ...

  3. Angular2入门系列教程5-路由(一)-使用简单的路由并在在路由中传递参数

    上一篇:Angular2入门系列教程-服务 上一篇文章我们将Angular2的数据服务分离出来,学习了Angular2的依赖注入,这篇文章我们将要学习Angualr2的路由 为了编写样式方便,我们这篇 ...

  4. Angular2入门系列教程4-服务

    上一篇文章 Angular2入门系列教程-多个组件,主从关系 在编程中,我们通常会将数据提供单独分离出来,以免在编写程序的过程中反复复制粘贴数据请求的代码 Angular2中提供了依赖注入的概念,使得 ...

  5. Angular2入门系列教程3-多个组件,主从关系

    上一篇 Angular2项目初体验-编写自己的第一个组件 好了,前面简单介绍了Angular2的基本开发,并且写了一个非常简单的组件,这篇文章我们将要学会编写多个组件并且有主从关系 现在,假设我们要做 ...

  6. Angular2入门系列教程2-项目初体验-编写自己的第一个组件

    上一篇 使用Angular-cli搭建Angular2开发环境 Angular2采用组件的编写模式,或者说,Angular2必须使用组件编写,没有组件,你甚至不能将Angular2项目启动起来 紧接着 ...

  7. ASP.NET MVC 入门系列教程

    ASP.NET MVC 入门系列教程 博客园ASP.NET MVC 技术专题 http://kb.cnblogs.com/zt/mvc/ 一个居于ASP.NET MVC Beta的系列入门文章,有朋友 ...

  8. Qt快速入门系列教程目录

    Qt快速入门系列教程目录

  9. Android视频录制从不入门到入门系列教程(一)————简介

    一.WHY Android SDK提供了MediaRecorder帮助开发者进行视频的录制,不过这个类很鸡肋,实际项目中应该很少用到它,最大的原因我觉得莫过于其输出的视频分辨率太有限了,满足不了项目的 ...

随机推荐

  1. LeetCode-4MedianofTwoSortedArrays(C#)

    # 题目 4. Median of Two Sorted Arrays There are two sorted arrays nums1 and nums2 of size m and n resp ...

  2. ABP文档 - 后台作业和工作者

    文档目录 本节内容: 简介 后台作业 关于作业持久化 创建一个后台作业 在队列里添加一个新作业 默认的后台作业管理器 后台作业存储 配置 禁用作业执行 Hangfire 集成 后台工作者 创建一个后台 ...

  3. 如何在nuget上传自己的包+搭建自己公司的NuGet服务器(新方法)

    运维相关:http://www.cnblogs.com/dunitian/p/4822808.html#iis 先注册一个nuget账号https://www.nuget.org/ 下载并安装一下Nu ...

  4. Java中的Socket的用法

                                   Java中的Socket的用法 Java中的Socket分为普通的Socket和NioSocket. 普通Socket的用法 Java中的 ...

  5. PHP好用但又容易忽略的小知识

    1.PHP函数之判断函数是否存在 当我们创建了自定义函数,并且了解了可变函数的用法,为了确保程序调用的函数是存在的,经常会先使用function_exists判断一下函数是否存在.同样的method_ ...

  6. iOS自定义model排序

    在开发过程中,可能需要按照model的某种属性排序. 1.自定义model @interface Person : NSObject @property (nonatomic,copy) NSStri ...

  7. Android中的LinearLayout布局

    LinearLayout : 线性布局 在一般情况下,当有很多控件需要在一个界面列出来时,我们就可以使用线性布局(LinearLayout)了,  线性布局是按照垂直方向(vertical)或水平方向 ...

  8. Android 调用百度地图API

    一.到 百度地图开发平台下载SDK http://lbsyun.baidu.com/index.php?title=androidsdk/sdkandev-download 1.点击自定义下载 2.下 ...

  9. SQL Server存储过程

    创建于2016-12-24 16:12:19 存储过程 概念: 1.存储过程是在数据库管理系统中保存的.预先编译的.能实现某种功能的SQL程序,它是数据库应用中运用比较广泛的 一种数据对象. 2.存储 ...

  10. Python学习基础

    1.使用范围: 大数据 .图像处理.web .运维.爬虫.自动化.科学计算 2.准备环境: linux/mac python 3.5.2 ipython vim/sublime/atom 3.列表 3 ...