這邊是上一篇Angular的主從元件開發的範例檔案:按此下載
創建 HeroService
使用Angular CLI創建一個名為hero的服務
1 |
ng generate service hero |
我們會看到在src/app下多出了兩個檔案:hero.service.spec.ts和hero.service.ts
打開src/app/hero.service.ts可以看到下面內容
1 2 3 4 5 6 7 8 |
import { Injectable } from '@angular/core'; @Injectable() export class HeroService { constructor() { } } |
注意到我們用@Injectable() 來宣告HeroService這個類別,代表這個類別可能本身有依賴注入,對Service來說是強烈建議要加上這個宣告
將HeroService提供給app使用
Service可以供appModule、或任何Component使用,如果要給appModule使用,
則需在src/app/app.module.ts的@NgModule裡加入
1 |
providers: [ HeroService ], |
這邊有更多NgModule的說明:NgModule
另外,若要使用CLI來自動完成providers的設定,則可以用下面的指令
1 |
ng generate service hero --module=app |
修改HeroesComponent去使用HeroService裡的資料
打開src/app/heroes/heroes.component.ts,修改成以下的內容
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 |
import { Component, OnInit } from '@angular/core'; import { HeroService } from '../hero.service';//1. 增加HeroService並移除HEROES import { Hero } from '../hero'; @Component({ selector: 'app-heroes', templateUrl: './heroes.component.html', styleUrls: ['./heroes.component.css'] }) export class HeroesComponent implements OnInit { heroes: Hero[];//2. 在這邊先不設定內容 selectedHero: Hero; constructor(private heroService: HeroService) { }//3. 宣告注入的service getHeroes(): void { this.heroes = this.heroService.getHeroes();//4. 取service內的資料放進變數內 } ngOnInit() { this.getHeroes();//5. ngOnInit會在初始化元件時被呼叫,在此時去取得heroes的值 } onSelect(hero: Hero): void { this.selectedHero = hero; } } |
讓getHeroes被更動時能夠被通知
Observable是RxJS library中很重要的一個功能。
當我們在src/app/hero.service.ts的getHeroes方法回傳值前面加上Observable宣告,當service內的資料變動時,其他注入的內容也會同步被異動
首先要先import下面兩個檔案
1 2 |
import { Observable } from 'rxjs/Rx'; import { of } from 'rxjs/observable/of'; |
然後在getHeroes的回傳直類型前加上Observable宣告
1 2 3 |
getHeroes(): Observable<Hero[]> { return of(HEROES); } |
注:若使用HttpClient.get<Hero[]>()亦會傳回Observable<Hero[]>,只是內容是由http傳來
在接收Observable物件時的方法也與非Observable物件的方式不同,過去若非Observable物件時,在hero.component.ts裡的getHeroes函數如下
1 2 3 |
getHeroes(): void { this.heroes = this.heroService.getHeroes(); } |
若要使用Observable宣告則須改為:
1 2 3 4 |
getHeroes(): void { this.heroService.getHeroes() .subscribe(heroes => this.heroes = heroes); } |
Observable.subscribe()是最關鍵的相異之處
最大的差異在於我們送出修改到伺服器傳回回應之間,未使用Observable.subscribe()方法時,它不會先凍結UI不讓使用者修改,而有可能會造成資料的不一致。而使用Observable.subscribe()可以避免這個問題。
本日範例下載: live example / download example