上一篇:Angular2入門系列教程6-路由(二)-使用多層級路由並在在路由中傳遞複雜參數css
感受這篇不是很好寫,由於涉及到網絡請求,若是採用真實的網絡請求,這個例子你們拿到手估計還要本身寫一個web api來提供調用;好在Angular2提供了本地模擬的api,能夠供咱們編寫方便;可是,真實使用的狀況每每與本地模擬有一些差異,會存在跨域等一系列問題;這些不在本篇文章的講解範圍以內,若是在.net下遇到跨域問題能夠直接私信我。html
Angular的http模塊並非Angular2的核心模塊,你並不必定要使用它;咱們有不少替代方案,好比你可使用jQuery的ajax,又或是本身編寫網絡請求;這都不重要,你不學習這一節的內容並不會影響你使用Angulargit
假設你已經跟上了咱們的進度,那,就開始吧github
首先咱們得要創建一個模擬的api文件,在咱們的data目錄下,內容以下web
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",ajax
位置在"devDependencies"下面,而後在命令行npm install一下npm
ok,這裏就是咱們的新的數據來源,那麼要如何使用呢?json
先到app.module.ts中配置,這裏貼出所有代碼吧bootstrap
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 20 @NgModule({ 21 declarations: [ 22 AppComponent, 23 ArticleComponent, 24 ArticledetailComponent, 25 CommentComponent 26 27 ], 28 imports: [ 29 BrowserModule, 30 FormsModule, 31 HttpModule, 32 ArticleDetailRoutingModule, 33 InMemoryWebApiModule.forRoot(InMemoryDataService),//in memery 34 AppRoutingModule 35 36 ], 37 providers: [BlogService,CommentService], 38 bootstrap: [AppComponent] 39 }) 40 export class AppModule { }
有備註的話我就不解釋什麼了,就是模塊導入而已api
接下來,在咱們的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
import { Injectable } from '@angular/core'; import {Http,Response ,Headers} from "@angular/http"; import 'rxjs/Rx'; import { Blog,BLOGS } from './blog'; @Injectable() export class BlogService { private apiUrl="app/blogs"; private headers = new Headers({'Content-Type': 'application/json'}); constructor(private http:Http){} getBlogs():Promise<Blog[]> { return this.http.get(this.apiUrl) .toPromise() .then(r=> r.json().data as Blog[]); //BLOGS; } getSelectedBlog(id:number):Promise<Blog> { let blog=new Blog(); return this.getBlogs().then(blogs=>blogs.find(x=>x.id==id)); } create(title: string):Promise<Blog> { return this.http .post(this.apiUrl, JSON.stringify({title: title}), {headers: this.headers}) .toPromise() .then(res => res.json().data); } editBlog(blog:Blog) { let editBlog= BLOGS.find(x=>x.id==blog.id); editBlog=blog; } addBlog(blog:Blog):string { var maxId=0; BLOGS.forEach(x=>{ if(x.id>maxId) maxId=x.id; }); blog.id=maxId; if(blog.title.length==0) { return "title 不能未空"; } else{ BLOGS.push(blog); return "success"; } } }
要將結果轉爲Promise,咱們須要導入rxjs,代碼如上
其餘咱們在構造函數中注入了http模塊,而後使用了它,咱們這裏就簡單得使用了get和post兩種方式,固然,Angualr2提供了put以及delete,用法都同樣,這裏就很少舉例了;上面的post方法使用了JSON.stirngify來處理咱們的參數,實際狀況中,咱們能夠直接將一個Object類型傳過去就好了,相似與下面的代碼
create(blog: Blog):Promise<Blog> { return this.http .post(this.apiUrl, blog, {headers: this.headers}) .toPromise() .then(res => res.json().data); }
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