Angular4记帐webApp练手项目之五(Angular4项目中建立service(服务)和使用http模块)

前言

以前写了那么多,不过都是静态页面。如今使用http模块与后端通讯,变可让咱们的应用活起来。 
我把后台服务写成了可跨域请求的webapi,这样在node上面调试起来就方便多了。css

建立服务模块

ng g service account
  • 1

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() { } } 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

添加一个方法node

getBillTypes() {
    console.log('这是service里的方法'); }
  • 1
  • 2
  • 3

引用服务

在accounting.component.ts里引用python

import {AccountService} from '../account.service';
  • 1
@NgModule({ providers: [ AccountService ], })
  • 1
  • 2
  • 3
  • 4
  • 5

推荐使用依赖注入的方式web

constructor(private service: AccountService) { service.getBillTypes(); // 调用方法 }
  • 1
  • 2
  • 3

查看下效果,提示错误。编程

Unhandled Promise rejection: No provider for AccountService! ; Zone: angular ; Task: Promise.then ; Value:
  • 1

原来是在app.module.ts 里面也要添加引用json

import {AccountService} from './account.service';
  • 1
providers: [AccountService],
  • 1

这下就完成了简单了例子。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', // 删除记帐信息 }; 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

在咱们的service中引入api

import {Urls} from './Model/model.url';
  • 1

整理方法

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); } }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

使用http模块

在咱们的app.module.ts中已经引入了

import { HttpModule } from '@angular/http';
  • 1

咱们要在account.service.ts中引入

import { Http } from '@angular/http'; import 'rxjs/add/operator/toPromise';
  • 1
  • 2

构造函数中注入依赖

constructor(private http: Http) { }
  • 1

修改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); }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

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; // 是否成功 } 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

在account.service.ts中引入并修改方法

import {Result} from './Model/model.result';
  • 1
getBillTypes(): Promise<Result> { // 获取记帐类型
    return this.http.get(this.urls.GetBillTypes) .toPromise() .then(response => response.json() as Result) .catch(this.handleError); }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

在accounting.component.ts中修改调用的方法

constructor(private service: AccountService) { service.getBillTypes().then(r => { console.log(r); }); }
  • 1
  • 2
  • 3

这正是咱们后台返回的数据且是json格式的。 
这里写图片描述 
这里咱们用到了自定义类型Result的做用呢,看控制台打印的数据,对数据没什么影响,可是对我写代码是有帮助的。看下面: 
这里写图片描述 
对,会提示,若是使用了类型里没有的字段,还会报错。这活生生把一个弱类型语言变成了强类型的。固然若是不喜欢,咱们能够不用自定义类。把自定义的Result换成any便可。 
这里写图片描述

完善service

添加三个自定义类型

// 记帐类型的数据结构 export class BillType { name: string; fontStyle: string; id: number; } 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
// 记帐的数据结构 export class Bill { id: number; creationTime: string; money: number; name: string; fontStyle: string; BillTypeId: number; }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

要细分就太多了,大体分红这几类吧,引入并完善咱们的方法

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); } }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48

最后完善修结果以下:

这里写图片描述

相关文章
相关标签/搜索