以前寫了那麼多,不過都是靜態頁面。如今使用http模塊與後端通訊,變可讓咱們的應用活起來。
我把後臺服務寫成了可跨域請求的webapi,這樣在node上面調試起來就方便多了。css
ng g service account
ng給咱們建立的模塊account.service.ts,內容以下。
有關@Injectable和@Component,都是angular中的關鍵字或者關鍵註解。經過註解來代表js文件的類型,以方便angular框架進行調用。
@Component表示該js文件所導出的類是組件。
@Injectable表示該js文件所導出的文件是服務,而服務是能夠經過注入來建立的。
服務的注入,是angular中用來剝離controller和業務邏輯的方式。java
import { Injectable } from '@angular/core'; @Injectable() export class AccountService { constructor() { } }
添加一個方法node
getBillTypes() {
console.log('這是service裏的方法'); }
在accounting.component.ts裏引用python
import {AccountService} from '../account.service';
@NgModule({ providers: [ AccountService ], })
推薦使用依賴注入的方式web
constructor(private service: AccountService) { service.getBillTypes(); // 調用方法 }
查看下效果,提示錯誤。編程
Unhandled Promise rejection: No provider for AccountService! ; Zone: angular ; Task: Promise.then ; Value:
原來是在app.module.ts 裏面也要添加引用json
import {AccountService} from './account.service';
providers: [AccountService],
這下就完成了簡單了例子。ng的編程風格愈來愈像咱們使用的c#,java等的編程風格。固然編程思想也是愈來愈和咱們後臺開發類似了。 c#
添加一個Model文件夾,在下面添加一個model.url.ts文件來存儲咱們的接口信息後端
const host = 'http://127.0.0.1:8001'; export const Urls= { GetBillTypes: host + '/api/bill/getbilltypes', // 獲取記帳類型 GetBills: host + '/api/bill/GetBills', // 獲取列表 GetCount: host + '/api/bill/GetCount', // 獲取統計信息 GetTotallCount: host + '/api/bill/GetTotallCount', // 獲取求和數據 AddBills: host + '/api/bill/AddBills', // 添加記帳信息 DeleteBill: host + '/api/bill/DeleteBill', // 刪除記帳信息 };
在咱們的service中引入api
import {Urls} from './Model/model.url';
整理方法
export class AccountService { private urls = Urls; constructor() { } getBillTypes(): void { console.log(this.urls.GetBillTypes); } GetBills(): void { console.log(this.urls.GetBills); } GetCount(): void { console.log(this.urls.GetCount); } GetTotallCount(): void { console.log(this.urls.GetTotallCount); } AddBills(): void { console.log(this.urls.AddBills); } DeleteBill(): void { console.log(this.urls.DeleteBill); } }
在咱們的app.module.ts中已經引入了
import { HttpModule } from '@angular/http';
咱們要在account.service.ts中引入
import { Http } from '@angular/http'; import 'rxjs/add/operator/toPromise';
構造函數中注入依賴
constructor(private http: Http) { }
修改getBillTypes方法試試,看請求返回數據和http.get返回的是什麼。
getBillTypes() {
console.log(this.urls.GetBillTypes); const data = this.http.get(this.urls.GetBillTypes) .toPromise() .then(response => console.log(response)); console.log(data); }
http.get(url)(或者post put delete),訪問服務器之後會返回一個observation對象,事實上是observation<服務器返回值>。經過toPromise轉換成promise對象之後,就能夠正常的使用then方法去處理返回值了。
經過promise的then方法,能夠得到到服務器的返回值。個返回值都是json字符串,而在angular仍是先按字符串處理。調用字符串的.json()方法轉化爲json數組或者json對象,繼續調用關鍵字as將json數組或者json對象轉化類,轉化的方式是屬性對應。
所以咱們修改方法,在model文件夾下添加自定義的Result類型,
// 接口返回數據格式 export class Result { error: any; // 錯誤時返回的信息 result: any; // 成功時返回的數據 success: boolean; // 是否成功 }
在account.service.ts中引入並修改方法
import {Result} from './Model/model.result';
getBillTypes(): Promise<Result> { // 獲取記帳類型
return this.http.get(this.urls.GetBillTypes) .toPromise() .then(response => response.json() as Result) .catch(this.handleError); }
在accounting.component.ts中修改調用的方法
constructor(private service: AccountService) { service.getBillTypes().then(r => { console.log(r); }); }
這正是咱們後臺返回的數據且是json格式的。
這裏咱們用到了自定義類型Result的做用呢,看控制檯打印的數據,對數據沒什麼影響,可是對我寫代碼是有幫助的。看下面:
對,會提示,若是使用了類型裏沒有的字段,還會報錯。這活生生把一個弱類型語言變成了強類型的。固然若是不喜歡,咱們能夠不用自定義類。把自定義的Result換成any便可。
添加三個自定義類型
// 記帳類型的數據結構 export class BillType { name: string; fontStyle: string; id: number; }
// 記帳的數據結構 export class Bill { id: number; creationTime: string; money: number; name: string; fontStyle: string; BillTypeId: number; }
要細分就太多了,大體分紅這幾類吧,引入並完善咱們的方法
export class AccountService {
private urls = Urls; constructor(private http: Http) { } getBillTypes(): Promise<Result> { // 獲取記帳類型 return this.get(this.urls.GetBillTypes); } GetBills(date, skipCount, user): Promise<Result> { const d = new URLSearchParams(); d.set('date', date); d.set('skipCount', skipCount); d.set('user', user); return this.get(this.urls.GetBills, d); } GetCount(date: string, type: number, user: string, GroupBy = 0): Promise<Result> { const d = new URLSearchParams(); d.set('date', date); d.set('type', type.toString()); d.set('user', user); d.set('GroupBy', GroupBy.toString()); return this.get(this.urls.GetCount, d); } GetTotallCount(user): Promise<Result> { return this.get(this.urls.GetTotallCount + '?user=' + user); } AddBills(data): Promise<Result> { return this.post(this.urls.AddBill, data); } DeleteBill(data: number): Promise<Result> { return this.post(this.urls.DeleteBill, data); } // 對get請求進行封裝 private get(url: string, data: URLSearchParams = null): Promise<Result> { return this.http.get(url, { search: data} ) .toPromise().then(r => r.json() as Result) .catch(this.handleError); } // 對post請求進行封裝 private post(url: string, data: any): Promise<Result> { return this.http.post(url, data) .toPromise().then(r => r.json() as Result) .catch(this.handleError); } // 捕獲異常並輸出 private handleError(error: any): Promise<any> { console.error('An error occurred', error); return Promise.reject(error.message || error); } }
最後完善修結果以下: