原文链接:hacking-with-angular

这篇文章我们来讲解如何使用service(服务),谈及服务我们就要了解什么是服务;在Angular中,我们所说的服务是指那些能够被其它的组件或者指令调用的单一的,可共享的代码块.服务能够使我们提高代码的利用率,方便组件之间共享数据和方法,方便测试和维护.

如果你看了上一篇文章Step 5 - Dependency Injection,你就会发现我们这一部分讲解的内容和上一篇有很多的相似之处;当然也有一些新的知识点,温故而知新嘛;好了让我们来开始今天的旅行吧.

首先我们还是切换回之前的quickstart版本,然后运行:

npm run start

可以看到My First Angular2 Travel,然后继续我们的铺垫工作;主要是三个部分:
1.将我们的组件模板使用单一的html模板来替代;
2.构建User类方便我们后面的使用;
3.构建我们的模拟数据,方便我们使用服务来获取这些数据;

首先我们来完成第一部分,修改app.component.ts@Component的元数据:template: '<h1>My First Angular2 Travel</h1>'改为:templateUrl: 'app/templates/main.html',然后我们在main.html中书写我们的模板代码:

<h1>My First Angular2 Travel</h1>

然后我们来进行第二个工作,创建我们的User类;为了展示方便,我们就给User两个属性吧,一个是id(number),一个是name(string);文件的路径是:app/classes/User.ts,具体的代码如下:

export class User {//id: number;//name: string;constructor(private id: number,private name: string){}
}

上面注释的部分是这个User类的简写,这个根据个人的喜好;你喜欢写就怎么写.

最后一项工作就是来创造我们的模拟数据,我们现在还没有学习如何在Angular2中使用HTTP,所以我们暂时将这些数据记录在一个文件中,然后导出这些数据,供我们接下来使用.我们的模拟数据文件路径是:app/mock/user.data.ts;下面是代码部分:

import {User} from "../classes/User";export const USERS: User[] = [{id: 1, name: 'dreamapple1'},{id: 2, name: 'dreamapple2'},{id: 3, name: 'dreamapple3'},{id: 4, name: 'dreamapple4'},{id: 5, name: 'dreamapple5'},{id: 6, name: 'dreamapple6'},{id: 7, name: 'dreamapple7'},{id: 8, name: 'dreamapple8'}
];

可以看到,我们导出了一个数组,这个数组的每一个元素都是一个User类的实例.

接下来,我们就要步入今天的主题了;构建一个服务,这个服务能够获取我们刚刚书写的模拟数据;首先不要忘记的是,service是一个类,然后这个类可以注入到别的组件
或者指令中去,还有一点就是我们知道,获取数据的服务往往都是异步的,所以我们使用了Promise去封装我们获取到的数据,来模拟异步请求;文件的路径是:app/service/user.service.ts,我们也遵循一个约定,服务的文件后缀是*.service.ts,前面的单词如果是多个的话就使用短横线来连接,比如SpecialUserService我们就写成special-user.service.ts,详细的部分请看代码:

import {User} from "../classes/User";
import {USERS} from "../mock/user.data";export class UserService {getUsers(): User[] {return Promise.resolve(USERS);}
}

关于上面代码的一些解释:因为我们的getUsers函数是有返回值的,它的返回值是一个数组,数组的每一个元素都是User类的实例,所以我们使用了getUsers(): User[],还有因为我们要模拟异步请求获取数据,所以我们使用了Promise,如果你对Promise有什么不懂的地方,可以看看这里.

接下来我们就要使用这个服务了,如何使用这个服务呢?在上一章节中我们已经讲解了许多种使用服务的方法;现在我们使用最简单的一种方式,直接使用providers来注入我们的服务,然后我们还要把我们获取到的数据展示到我们的模板中,具体的代码如下所示:

import {Component} from '@angular/core';
import {User} from "./classes/User";
import {UserService} from "./services/user.service";/** 别忘记了使用@前缀* 这里相当于组件视图*/
@Component({selector: 'my-app',//template: '<h1>My First Angular2 Travel</h1>',templateUrl: 'app/templates/main.html',providers: [UserService]
})/** 导出这个组件,也就是一个类* 这里相当于组件控制器*/
export class AppComponent {users: User[];constructor(private userService: UserService){//noinspection TypeScriptUnresolvedFunctionthis.userService.getUsers().then(users => this.users = users)}
}

我们也要改动main.html的内容:

<h1>My First Angular2 Travel</h1>
<ul><li *ngFor="let user of users">{{user.name}}</li>
</ul>

这时我们打开浏览器,就会看到我们想要的结果:

上面的写法是有一些问题的,构造函数是为了简单的初始化工作而设计的,比如把构造函数的参数赋值给属性.它的负担不应该过于沉重.所以我们把数据的获取放在了组件的生命周期的钩子函数中去,如果你不了解组件的生命周期的话,那么你可以看看这里,在这里我们使用了ngOnInit;我们修改一下上面的代码:

import {Component, OnInit} from '@angular/core';
import {User} from "./classes/User";
import {UserService} from "./services/user.service";/** 别忘记了使用@前缀* 这里相当于组件视图*/
@Component({selector: 'my-app',//template: '<h1>My First Angular2 Travel</h1>',templateUrl: 'app/templates/main.html',providers: [UserService]
})/** 导出这个组件,也就是一个类* 这里相当于组件控制器*/
export class AppComponent implements OnInit{users: User[];constructor(private userService: UserService){}getUsersData() {this.userService.getUsers().then(users => this.users = users);}ngOnInit() {this.getUsersData();}}

上面代码的一些解释,首先我们在@angular/core中导出了OnInit这个接口,然后我们又通过组件中的ngOnInit方法实现了这个接口;将构造函数中的获取数据的业务提取了出来,这种做法是组件初始化的时候获取数据比较好的一种方案.我们在后面的文章中也会讲解关于组件或者指令生命周期的文章.

最后,我们还可以更真实的的去模拟从服务器读取数据的操作;我们可以通过使用setTimeout来延时获取我们的数据,这就很好地模拟了我们从服务器获取数据的操作;具体的代码部分看下面:

import {User} from "../classes/User";
import {USERS} from "../mock/user.data";export class UserService {getUsers(): Promise<User[]> {return Promise.resolve(USERS);}getMockUsers(): Promise<User[]> {return new Promise(resolve => setTimeout(resolve(USERS), 2000)).then(() => this.getUsers());}
}

首先需要注意的一点是,我们之前写的代码把getUsers()函数的返回值定义为User[],其实更准确的应该是Promise<User[]>;我们接下来写的函数getMockUsers()利用setTimeout延时返回了我们的模拟数据.

其实我们的程序里还有一个小错误,不容易被发现;当我在构建的时候我发现了下面的错误:

它提醒我们说,Property 'id' is private in type 'User' but not in type '{ id: number; name: string; }'.这是因为我们把id作为User的私有属性了,但是在{ id: number; name: string; }对象中,id不是私有的属性;要解决这个问题有多种思路,你可以将我们的模拟数据使用User类来创建,或者将idname作为public属性.那我们就取一个简单的方法,将属性定义为public.User类的代码修改如下:

export class User {id: number;name: string;//constructor(//    private id: number,//    private name: string//){}
}

在TypeScript里,每个成员默认为是public的.所以上面的写法是很简便的.

到这里我们要说的内容已经说完了,源代码可以参考这里angular2-travel,当然欢迎批评指正.

掌握Angular2的服务(service)相关推荐

  1. 掌握 Angular2 的服务 (service)

    这篇文章我们来讲解如何使用service(服务),谈及服务我们就要了解什么是服务;在Angular中,我们所说的服务是指那些能够被其它的组件或者指令调用的单一的,可共享的代码块.服务能够使我们提高代码 ...

  2. linux 进程间通信 dbus-glib【实例】详解三 数据类型和dteeth(类型签名type域)(层级结构:服务Service --> Node(对象、object) 等 )(附代码)

    linux 进程间通信 dbus-glib[实例]详解一(附代码)(d-feet工具使用) linux 进程间通信 dbus-glib[实例]详解二(上) 消息和消息总线(附代码) linux 进程间 ...

  3. android打开位置服务,Android - 位置定位(Location)服务(Service)类的基本操作

    位置定位(Location)服务(Service)类的基本操作 本文地址: http://blog.csdn.net/caroline_wendy 定位服务(Location Service),能够确 ...

  4. Windows服务(Service)安装及启动停止方案

    目录 一.创作背景 二.问题解决 2.1 安装Windows service服务 2.2 主方法Main()主方法改写 2.3 安装service服务/卸载service服务 2.4 服务启停 2.5 ...

  5. 开机启动一个服务Service,启动后没有界面后台暗暗运行

    原文来自:http://blog.163.com/shaocpa@126/blog/static/553577572012418103732417/ 如果开机启动一个Activity,开机首先看的界面 ...

  6. 服务Service的基本用法

    作为 Android四大组件之一, 服务也少不了有很多非常重要的知识点,那自然要从最基本的用法开始学习了. 定义一个服务: public class MyService extends Service ...

  7. ubuntu启动、关闭、重启服务service命令

    查看当前所有服务 service --status-all 结果如下: zwl@zwl-NB50TJ1-TK1:~$ service --status-all[ + ] acpid[ - ] alsa ...

  8. android创建标题栏,【Android】利用服务Service创建标题栏通知

    创建标题栏通知的核心代码 public void CreateInform() { //定义一个PendingIntent,当用户点击通知时,跳转到某个Activity(也可以发送广播等) Inten ...

  9. [云原生专题-33]:K8S - 核心概念 - 服务Service管理、服务发现、负载均衡

    作者主页(文火冰糖的硅基工坊):文火冰糖(王文兵)的博客_文火冰糖的硅基工坊_CSDN博客 本文网址:https://blog.csdn.net/HiWangWenBing/article/detai ...

最新文章

  1. 检查点重做检查点队列简单总结Strut2教程-java教程
  2. python详细安装步骤-Pycharm及python安装详细教程(图解)
  3. 利用pyinstaller打包Python程序为一个可执行文件
  4. git生成SSH-Key
  5. 操作系统源代码_国产操作系统“之光”?Windows XP绝密源代码泄露,BT种子已在网上疯传...
  6. 清空网站浏览记录就行啦?看Python如何实时监控网站浏览记录
  7. Google 要放弃 Android 了?
  8. 智慧城市纳入北京重点支持高新领域
  9. CVTE 2016 春季实习校招一面(C++后台)
  10. 遍历二叉树(四种方式:前序、中序、后序、层序)
  11. linux hal 结构图
  12. 俄罗斯方块c语言代码 vc 6.0,VC++6.0俄罗斯方块代码
  13. python内置函数系列之str(一)(持续更新)
  14. 计算机应用与维修电竞与管理,电子竞技运动与管理-五年制高技招生专业-广州市白云工商技师学院_广州市白云工商高级技工学校_信息工程系(计算机系)...
  15. gts测试提示 Test failed due to unrecognized service account for this product, please submit an initial G
  16. python设计迷宫_用Python制作迷宫GIF
  17. layui 如何取得select下拉框选中的值
  18. 用 JS 进行 Base64 编码、解码
  19. CSS入门系列(一)概述和html结合的方式
  20. Eslint semi 结尾分号设置与否

热门文章

  1. 十大最急需IT技术人才榜:Java开发人员领跑
  2. Python 为什么要使用描述符?
  3. Gradle 学习二
  4. 同是产品经理,为什么几年后会差距这么大?
  5. 90后招你惹你了?去你的佛系!
  6. 一夜吸粉200万被封杀,微信都有哪些逆鳞?
  7. 如何当好PM?请求大家积极讨论
  8. amchart折线图示例
  9. 发展医疗大数据 需捅破各层窗户纸
  10. 《图数据库(第2版)》——2.1 关系型数据库缺少联系