iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 5
3

這邊是上一篇Angular的主從元件開發的範例檔案:按此下載
本文同步發佈於:Claire's BLOG

創建 HeroService

使用Angular CLI創建一個名為hero的服務

ng generate service hero

我們會看到在src/app下多出了兩個檔案:hero.service.spec.tshero.service.ts

打開src/app/hero.service.ts可以看到下面內容

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裡加入

providers: [ HeroService ],

這邊有更多NgModule的說明:NgModule
另外,若要使用CLI來自動完成providers的設定,則可以用下面的指令

ng generate service hero --module=app

修改HeroesComponent去使用HeroService裡的資料

打開src/app/heroes/heroes.component.ts,修改成以下的內容

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.tsgetHeroes()方法回傳值前面加上Observable宣告,當service內的資料變動時,其他注入的內容也會同步被異動 首先要先import下面兩個檔案

import { Observable } from 'rxjs/Rx';
import { of } from 'rxjs/observable/of';

然後在getHeroes的回傳直類型前加上Observable宣告

getHeroes(): Observable {
  return of(HEROES);
}

注:若使用HttpClient.get<Hero[]>()亦會傳回Observable<Hero[]>,只是內容是由http傳來
在接收Observable物件時的方法也與非Observable物件的方式不同,過去若非Observable物件時,在hero.component.ts裡的getHeroes函數如下

getHeroes(): void {
  this.heroes = this.heroService.getHeroes();
}

若要使用Observable宣告則須改為:

getHeroes(): void {
  this.heroService.getHeroes()
      .subscribe(heroes => this.heroes = heroes);//差異在這邊
}

Observable.subscribe()是最關鍵的相異之處
最大的差異在於我們送出修改到伺服器傳回回應之間,未使用Observable.subscribe()方法時,它不會先凍結UI不讓使用者修改,而有可能會造成資料的不一致。而使用Observable.subscribe()可以避免這個問題。

本日範例下載: live example / download example


上一篇
[新手教程-4] Angular的主從元件開發
下一篇
[新手教程-6] 使用Routing來切換頁面
系列文
用30天深入Angular 5的世界31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 則留言

0
Blackie Tsai
iT邦新手 5 級 ‧ 2017-12-24 08:38:28

部落格的連結好像有問題

Oops! That page can’t be found.

已修復~!感謝回報

0
增廣建文
iT邦研究生 5 級 ‧ 2018-09-13 11:44:19

https://stackoverflow.com/questions/49840152/i-get-an-error-when-learning-angular-has-no-exported-member-observable

import {Observable, of} from 'rxjs';

RxJS 6/ Anuglar 6 如果有遇到rxjs的import問題可以改為上述試試看

謝謝你的資訊!!

我要留言

立即登入留言