AngularJS2.0 学习笔记06:service组件(在线算命App 引入数据服务器)

2016年09月20日 APP开发, javascript 暂无评论 阅读 27 views 次

service组件

对于初学者,在学习之前请阅读前面笔记内容。

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

service 组件命名规范

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

创建一个Hero Service

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

import {Injectable} from 'angular2/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: 1,
 name: '上上',
 desc: '大吉大利,百事顺遂,赶紧去买彩票' },
 { id: 2,
 name: '上吉',
 desc: '天时、地利又人和,家庭和睦,身体健康,会朋友喝酒吧' },
 { id: 3,
 name: '中吉',
 desc: '苦尽甘来,风雨之后见彩虹,要转好运了' },
 { id: 4,
 name: '中平',
 desc: '黎明前的曙光。寓象中不是“怀才不遇”,而是“怀才待遇”。多嘱求者“一动不若一静”。无大喜亦无大悲。在这五种签意中,最欣赏的还是中平签,因为它更符合百姓,贴近生活。其不似“上上”般如中头彩;不似“上吉”般天时、地利又人和;不似“中吉”般起起落落,如咖啡加糖;“中平”更多的是人们常求的“平平”和“淡淡”。' },
 { id: 5,
 name: '下下',
 desc: '凶多吉少.否极泰来,物极必反,再熬一熬就过去了。要不再抽一签?' }
 ];

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

import {HEROES} from './mock-heroes';
import {Injectable} from 'angular2/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 'angular2/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();

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()的函数体。

完整代码

hero.service.ts

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

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

app.component.ts

import {Component, OnInit} from 'angular2/core';
import {Hero} from './hero';
import {HeroDetailComponent} from './hero-detail.component';
import {HeroService} from './hero.service';
@Component({
  selector: 'my-app',
  template:`
    <h1>{{title}}</h1>
    <h2>My Heroes</h2>
    <ul class="heroes">
      <li *ngFor="#hero of heroes"
        [class.selected]="hero === selectedHero"
        (click)="onSelect(hero)">
        <span class="badge">{{hero.id}}</span> {{hero.name}}
      </li>
    </ul>
    <my-hero-detail [hero]="selectedHero"></my-hero-detail>
  `,
  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: 1,
 name: '上上',
 desc: '大吉大利,百事顺遂,赶紧去买彩票' },
 { id: 2,
 name: '上吉',
 desc: '天时、地利又人和,家庭和睦,身体健康,会朋友喝酒吧' },
 { id: 3,
 name: '中吉',
 desc: '苦尽甘来,风雨之后见彩虹,要转好运了' },
 { id: 4,
 name: '中平',
 desc: '黎明前的曙光。寓象中不是“怀才不遇”,而是“怀才待遇”。多嘱求者“一动不若一静”。无大喜亦无大悲。在这五种签意中,最欣赏的还是中平签,因为它更符合百姓,贴近生活。其不似“上上”般如中头彩;不似“上吉”般天时、地利又人和;不似“中吉”般起起落落,如咖啡加糖;“中平”更多的是人们常求的“平平”和“淡淡”。' },
 { id: 5,
 name: '下下',
 desc: '凶多吉少.否极泰来,物极必反,再熬一熬就过去了。要不再抽一签?' }
 ];

code:ang2.0

给我留言

您必须 登录 才能发表留言!

Copyright © 大一网 保留所有权利.  

用户登录

分享到: