Angular 4入门教程系列:6:Tour Of Heroes之服务和依赖注入

来源:互联网 发布:怎么在淘宝上开S音速店 编辑:程序博客网 时间:2024/06/05 07:46

这里写图片描述
这篇文章我们将会聚焦于服务和依赖注入。同时也会学到lifecycle hook的ngOnInit以及Promise如何进行异步服务的处理。

学习目标

  • 解耦数据的提供方式,生成HeroService
  • 使用依赖注入的方式提供数据
  • 使用Promise进行异步服务处理

学习时间

大概需要10分钟

模拟数据mock-heroes.ts

程序目前的做法是使用一个包含10个数据的对象数组提供数据,但是实际的项目中一般比这要复杂很多,比如数据往往由后端提供,同时除了性能之外,我们还需要测试的方便性,总不能测试的时候伴随着大量的代码修正才能进行吧,所以都放在app.component.ts中显然是不合适的,虽然不能一步到位,我们可以先把提供数据的对象数组给移出来,专门用一个名为mock-heroes.ts文件用于存放此数据,在mock-heroes.ts文件中export HEROES数组,具体代码如下:

/workspace/HelloAngular/src/app # cat mock-heroes.tsimport { Hero } from './hero';export const HEROES: Hero[] = [  { id: 11, name: 'Mr. Nice' },  { id: 12, name: 'Narco' },  { id: 13, name: 'Bombasto' },  { id: 14, name: 'Celeritas' },  { id: 15, name: 'Magneta' },  { id: 16, name: 'RubberMan' },  { id: 17, name: 'Dynama' },  { id: 18, name: 'Dr IQ' },  { id: 19, name: 'Magma' },  { id: 20, name: 'Tornado' }];/workspace/HelloAngular/src/app #

除去数据之后的app.component.ts

把数据移出去之后,app.component.ts文件变得轻快了一些:

/workspace/HelloAngular/src/app # cat app.component.tsimport { Component } from '@angular/core';import { Hero } from './hero'import { HEROES } from './mock-heroes'@Component({  selector: 'app-root',  templateUrl: './app.component.html',  styleUrls: ['./app.component.css']})export class AppComponent {  title = 'Tour of Heroes';  heroes = HEROES;  selectedHero: Hero;  onSelect(hero: Hero): void {    this.selectedHero = hero;  }}/workspace/HelloAngular/src/app # 

确认一下发现画面能够正常显示 :
这里写图片描述

HeroService服务

但是这其实只是一个简单的物理位置移动而已,接下来我们把其拆出来一个提供数据的独立的服务HeroService.创建一个文件名为hero.service.ts的文件,我们现在要做的事情是通过这个服务来提供Hero数据,app.component.ts将会不直接去看mock-heroes.ts,内容很简单,具体代码如下:

/workspace/HelloAngular/src/app # cat hero.service.tsimport { Injectable } from '@angular/core';import { Hero } from './hero';import { HEROES } from './mock-heroes';export class HeroService {  getHeroes(): Hero[] {    return HEROES;  }}/workspace/HelloAngular/src/app #

调用服务

如何调用服务,首先用一下官网严重不推荐但最容易理解的方式,直接new一下。你说不好我就不用岂不是很没有面子,看看怎么new

/workspace/HelloAngular/src/app # cat app.component.tsimport { Component } from '@angular/core';import { Hero } from './hero'import { HeroService } from './hero.service'@Component({  selector: 'app-root',  templateUrl: './app.component.html',  styleUrls: ['./app.component.css']})export class AppComponent {  title = 'Tour of Heroes';  selectedHero: Hero;  heroService: HeroService;  heroes: Hero[];  onSelect(hero: Hero): void {    this.selectedHero = hero;  }  constructor() {    this.heroService = new HeroService();    this.heroes = this.heroService.getHeroes();  }}/workspace/HelloAngular/src/app # 

确认一下发现画面能够正常显示 :
这里写图片描述

依赖注入

我们new出来了一个HeroService,然后通过它成功去到了数据,但是也会得到深度解耦依赖症患者的严重愤怒,我们不能理解他们的愤怒就像他们不能理解我们面对西二旗最后一趟车的焦虑一样,虽然西二旗没有最后一趟车,现在已经能够调用到了之后,我们看看如何使用依赖注入的方式吧。

删除new的构建

删除new所在的构建语句,所需要的依赖由Angular来注入吧,删除完毕之后,app.component.ts成了这个样子:

整体还好,构造函数提供一个私有的HeroService的变量,然后我们的程序就不再管构建HeroService的对象,直接用就好,这样还可以省去一个类的成员变量HeroService。

/workspace/HelloAngular/src/app # cat app.component.tsimport { Component } from '@angular/core';import { Hero } from './hero'import { HeroService } from './hero.service'@Component({  selector: 'app-root',  templateUrl: './app.component.html',  styleUrls: ['./app.component.css'],  providers: [HeroService]})export class AppComponent {  title = 'Tour of Heroes';  selectedHero: Hero;  heroes: Hero[];  onSelect(hero: Hero): void {    this.selectedHero = hero;  }  constructor(private heroService: HeroService) {    this.heroes = heroService.getHeroes();  }}/workspace/HelloAngular/src/app # 

虽然我们不构建HeroService对象,并不意味这没有人去构建,我们需要提供足够信息让Angular去做,所以在@Component装饰器中非常重要的那行”providers: [HeroService]”就起到了这个作用,这样终于没有new了,大家的焦虑都可以稍微缓解一下了,其实也没有那么神奇,无非工厂模式或者变种的实现而已。

确认一下发现画面能够正常显示 :
这里写图片描述

Lifecycle hook

我们现在的数据写在构造函数里面也会引起很多不必要的问题,比如至少构建对象很复杂,构建对象很复杂的话就会引起很多重大问题:连个对象都没有,什么时候才能结婚,什么时候才能实现你的中国梦。不写在构造函数里面写在哪里:ngOnInit里面就可以,ngOnInit是个什么鬼,看他的名字你就知道是初期化的嘛。总而言之,没有对象非常严重,赶紧解决。可是现在构造函数里面就只有一句了,也要移走麽,移到什么地方呢?可以创建一个函数,然后再ngOnInit中调用,这里直接写道ngOnInit中以确认执行过程即可:

然后就做如下几件事情:

  • 把OnInit从angular/core中import进来
  • export class AppComponent的时候告诉它你要Implements OnInit
  • 在ngOnInit中调用新写的函数取得Hero的数据

原来一行代码实现的,显现看起来似乎更麻烦,然后再LifeCycle的OnInit中来调用这一行,让人都不想取数据了。不过大型的项目解耦起来比这要复杂太多了,看似麻烦,其实也是有具体的应用场景的,不再赘述。我们到目前为止已经写成了如下的代码:

/workspace/HelloAngular/src/app # cat app.component.tsimport { Component } from '@angular/core';import { OnInit    } from '@angular/core';import { Hero } from './hero';import { HeroService } from './hero.service';@Component({  selector: 'app-root',  templateUrl: './app.component.html',  styleUrls: ['./app.component.css'],  providers: [HeroService]})export class AppComponent implements OnInit {  title = 'Tour of Heroes';  selectedHero: Hero;  heroes: Hero[];  onSelect(hero: Hero): void {    this.selectedHero = hero;  }  ngOnInit(): void{    this.heroes = this.heroService.getHeroes();  }  constructor(private heroService: HeroService) {  }}/workspace/HelloAngular/src/app #

确认一下发现画面能够正常显示 :
这里写图片描述

异步服务

程序的服务很多时候都是异步的,浏览器并不会像阻塞式socket编程那样一直等待而是会立即返回。这种情况下我们可以使用ES6中所支持的Promise方式。

改写HeroService

使用Promise方式,HeroService的写法需要进行改变,代码修改如下:

/workspace/HelloAngular/src/app # cat hero.service.tsimport { Injectable } from '@angular/core';import { Hero } from './hero';import { HEROES } from './mock-heroes';@Injectable()export class HeroService {  getHeroes(): Promise<Hero[]> {    return Promise.resolve(HEROES);  }}/workspace/HelloAngular/src/app #

改写app.component.ts

与之相对应的,app.component.ts中方式也需要重写,所以改写ngOnInit中的写法:

/workspace/HelloAngular/src/app # cat app.component.tsimport { Component } from '@angular/core';import { OnInit    } from '@angular/core';import { Hero } from './hero';import { HeroService } from './hero.service';@Component({  selector: 'app-root',  templateUrl: './app.component.html',  styleUrls: ['./app.component.css'],  providers: [HeroService]})export class AppComponent implements OnInit {  title = 'Tour of Heroes';  selectedHero: Hero;  heroes: Hero[];  onSelect(hero: Hero): void {    this.selectedHero = hero;  }  ngOnInit(): void{    this.heroService.getHeroes().then(heroes => this.heroes = heroes);   }  constructor(private heroService: HeroService) {  }}/workspace/HelloAngular/src/app # 

确认一下发现画面能够正常显示 :
这里写图片描述

总结

通过这篇文章,我们学习到了Angular的服务依赖注入的方式以及OnInit等Lifehook的使用方式,以及如何使用Promise的方式进行异步方式的服务提供,下篇文章我们将会学习一下Angular的路由。

阅读全文
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 外地人在北京交社保退休怎么办 身份证掉了单位宿舍怎么办居住证 广州租住单位宿舍怎么办居住证 公司u盾丢了怎么办 北京办了居住卡怎么办延期 商铺被陌生人注册左公司怎么办 营业执照年检登录密码忘了怎么办 欠人家钱没钱还怎么办 欠钱实在没钱还怎么办 党关系丢了10年怎么办? 离婚后生孩子怎么办出生证明 注册公司没有注册地址怎么办 银行流水不够2倍怎么办 个体户小店怎么办五险 姓和名五行相克怎么办? 三星s7刷机后计算器没有了怎么办 线雕鼻子山根鼓怎么办 在日本没有日币怎么办 明知合同回扣特别高怎么办 医院药品断货了怎么办 空腹吃菠萝胃疼怎么办 小孩黑户口怎么办上户 别人说名字起大了怎么办? 念佛号时心老是不集中怎么办 扑lv期嗓子痛头痛怎么办 公众号忘记了账号怎么办 公众号账号密码忘记了怎么办 现实生活被小人缠上怎么办 五行缺木和水怎么办 八字火旺的人怎么办 综合旺衰得分负怎么办 妈妈误打死一只黄鼠狼怎么办 油笔画在白墙上怎么办 壁纸上的水彩笔怎么办 隐形拉链头脱了怎么办 拉链的一边掉了怎么办 帝豪gs加了乙醇汽油怎么办 命理五行缺木怎么办 微信改名含有特殊符号怎么办 户口名字打错了怎么办 寻仙会心几率差怎么办