angular2学习笔记(4)

service组件:

在多个组件中我们需要使用hero的数据,在生产环境下,这些数据或许是从网络服务器端获取,或许是本地静态数据,然而我们又不想copy到这个组件,copy到那个组件中。我们可以创建一个唯一的可重复使用的请求数据的组件。Angular2.0中将使用注入的方式给组件注入service组件。

service 组件命名规范

  • 所有的Service组件以service结尾。
  • 文件名全部是小写,并且多个单词用短线连接-。例如:shop-car.service.ts
  • 文件名字尽量与Service名称相符。

创建一个Hero Service

在app目录下新建一个文件hero.service.ts,内容如下:

import {Injectable} from '@angular/core';

@Injectable()
export class HeroService {
   getHeroes() {

   }
}

上面导入了Injectable组件,并且在HeroService添加了@Injectable()注解。提供了一个获取hero data的接口。 对于HeroServicehero data 可以是服务器端HTTP请求获取,也可以是本地静态数据。

创建一个模拟数据mock-heroes.ts文件,把前面AppComponent中的Hero数据copy到这里,内容如下:

import {Hero} from './hero';
export var HEROES: Hero[] = [
  { "id": 11, "name": "奥巴马" },
  { "id": 12, "name": "希维尔" },
  { "id": 13, "name": "兰博" },
  { "id": 14, "name": "雷克顿" },
  { "id": 15, "name": "提莫" },
  { "id": 16, "name": "德芙兰" },
  { "id": 17, "name": "德玛" },
  { "id": 18, "name": "波比" },
  { "id": 19, "name": "布兰德" },
  { "id": 20, "name": "卡尔" }
];

导出的HEROES可以在其他组件中使用,例如在HeroService中使用:

import {HEROES} from './mock-heroes';
import {Injectable} from '@angular/core';

@Injectable()
export class HeroService {
  getHeroes() {
    return HEROES;
  }
}

注入HeroService

在Angular中使用constructor定义私有变量,constructor中的变量一般前面带_表示是要注入的变量

constructor(private _heroService: HeroService) { }

@Component中通过provider属性注册HeroService

providers: [HeroService]

在组件树中也可以使用父组件的provider中的Service。

AppComponent中添加getHero方法。

getHeroes() {
    this.heroes = this._heroService.getHeroes();
  }

ngOnInit的使用

上面在AppComponent组件中定义的getHeroes我们在哪儿调用呢 ,可能会想到在组件初始化的时候调用。

Angular提供了ngOnInit方法,ngOnInit是在组件初始化的时候,由Angular内部系统自动调用,我们可以在组件初始化的时候加入我们自己的业务代码,比如获取组件template中需要的数据,ngOnInit方法是组件生命周期的钩子函数。所以可以在ngOnInit中调用getHeroes

import {OnInit} from '@angular/core';

export class AppComponent implements OnInit {
  ngOnInit() {
      getHeroes() ;
  }
}

Async Services and Promises

HeroServicegetHeroes()函数内,获取数据有时候是从服务器端Http获取,有时候是本地立即能返回的数据, 为了在加载Angular组件时,获取数据不受Http请求延时的影响,我们需要使用声明获取数据是同步(Promises)还是异步

PromisesCommonJS规范中提出的,所谓Promise,字面上可以理解为“承诺”,就是说A调用B,B返回一个“承诺”给A,然后A就可以在写计划的时候这么写:当B返回结果给我的时候,A执行方案S1,反之如果B因为什么原因没有给到A想要的结果,那么A执行应急方案S2,这样一来,所有的潜在风险都在A的可控范围之内了。

上面这句话,翻译成代码类似:

    var resB = B();  
    var runA = function() {  
        resB.then(
           function(object) {
             .....
            },
           function(error) {
            ......
            }
        );  
    };  

    runA();

更多关于Promise的资料

  • Javascript Promise 为什么这么迷人
  • avaScript Promise启示录

HeroService中使用Promises

getHeroes() {
  return Promise.resolve(HEROES);
}

使用Promise中的then回调函数,then函数带一个参数data。

getHeroes() {
  this._heroService.getHeroes().then(heroes => this.heroes = heroes);
}

getHeroes中的then回调函数只写了success时候的方法,没有对error进行处理。并且在success处理中使用了箭头函数。

箭头函数是ES6的新规范。箭头函数简单的说就是:=>前面是函数的参数,=>后面的内容是回调函数then()的函数体。

关于箭头函数的相关在知识 大家可以百度一下,这里收集了几篇

  • 探秘ES6 系列专栏(七):箭头函数
  • 箭头函数

完整代码

hero.service.ts

import {Hero} from './hero';
import {HEROES} from './mock-heroes';
import {Injectable} from '@angular/core';
@Injectable()
export class HeroService {
  getHeroes() {
    return Promise.resolve(HEROES);
  }

  // 模拟延迟请求
  getHeroesSlowly() {
    return new Promise<Hero[]>(resolve =>
      setTimeout(()=>resolve(HEROES), 2000) // 2 seconds
    );
  }
}

app.component.ts

import {Component, OnInit} from '@angular/core';
import {Hero} from './hero';
import {HeroDetailComponent} from './hero-detail.component';
import {HeroService} from './hero.service';
@Component({
  selector: 'my-app',
  template:`
    

{{title}}

My Heroes

  • {{hero.id}} {{hero.name}}
`
, styles:[` .selected { background-color: #CFD8DC !important; color: white; } .heroes { margin: 0 0 2em 0; list-style-type: none; padding: 0; width: 10em; } .heroes li { cursor: pointer; position: relative; left: 0; background-color: #EEE; margin: .5em; padding: .3em 0em; height: 1.6em; border-radius: 4px; } .heroes li.selected:hover { color: white; } .heroes li:hover { color: #607D8B; background-color: #EEE; left: .1em; } .heroes .text { position: relative; top: -3px; } .heroes .badge { display: inline-block; font-size: small; color: white; padding: 0.8em 0.7em 0em 0.7em; background-color: #607D8B; line-height: 1em; position: relative; left: -1px; top: -4px; height: 1.8em; margin-right: .8em; border-radius: 4px 0px 0px 4px; } `], directives: [HeroDetailComponent], providers: [HeroService] }) export class AppComponent implements OnInit { public title = 'Tour of Heroes'; public heroes: Hero[]; public selectedHero: Hero; constructor(private _heroService: HeroService) { } getHeroes() { this._heroService.getHeroes().then(heroes => this.heroes = heroes); } ngOnInit() { this.getHeroes(); } onSelect(hero: Hero) { this.selectedHero = hero; } }

mock-heroes.ts

import {Hero} from './hero';
    export var HEROES: Hero[] = [
  { "id": 11, "name": "奥巴马" },
  { "id": 12, "name": "希维尔" },
  { "id": 13, "name": "兰博" },
  { "id": 14, "name": "雷克顿" },
  { "id": 15, "name": "提莫" },
  { "id": 16, "name": "德芙兰" },
  { "id": 17, "name": "德玛" },
  { "id": 18, "name": "波比" },
  { "id": 19, "name": "布兰德" },
  { "id": 20, "name": "卡尔" }
];

你可能感兴趣的:(Angular2)