iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 8
0
Modern Web

Angular - 從零開始系列 第 8

Angular - 從零開始 - Day8 -Service 服務元件的基本認識

  • 分享至 

  • xImage
  •  

angular

什麼服務元件

service 元件是可以把共用的行為或程式邏輯放在此元件中,並且透過相依注入的方法,使其他元件可以取用。

建立服務元件

本次範例

本次範例路徑如下圖,所使用為 app 資料夾底下的 app.module.ts 以及 feature.service.ts。

app

建立服務元件的起手式程式碼,不需要打 service,只要打元件名稱即可。

ng g s 元件名稱

EX. 自定義命名一個功能服務元件,只要在終端機輸入 ng g s feature,就會建立一個名稱為 feature 的服務元件。

feature

裡面預設程式碼如下,因為也是元件,所以結構看起來很相似。

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

@Injectable({
  providedIn: "root",
})
export class FeatureService {
  constructor() {}
}

其實服務元件也是一個類別,裡面放的內容只有兩個,屬性或是方法

注入 service

建立好 service 後,要回到 app.module.ts 中,注入 service,Angular 10 很貼心的在我們新增 service 後會自動幫我們建立一個 providers 的屬性,其組成為陣列,代表可以放多個 service。

@NgModule({
  declarations: [
    AppComponent,
    HomeComponent,
    SecondComponent,
    Home1Component,
    Home2Component,
  ],
  imports: [BrowserModule, AppRoutingModule, FormsModule], // 加入倒 imports
  providers: [], // service 使用
  bootstrap: [AppComponent],
})

雖然已經建立好,但還沒放入我們剛剛建立的 service,所以要手動輸入剛剛建立的 service 名稱,所以只要把 featureService 放入陣列即可,放入後也會自動 import 到 app.module.ts 內。

因為 VScode 有內建 IntelliSense 功能,所以只要打關鍵字就會出現相對應的選項,選到想要的選項後按下 tab 就可以完成囉!

import { FeatureService } from './feature.service'; // service 新增

@NgModule({
  declarations: [
    AppComponent,
    HomeComponent,
    SecondComponent,
    Home1Component,
    Home2Component,
  ],
  imports: [BrowserModule, AppRoutingModule, FormsModule], // 加入倒 imports
  providers: [FeatureService], // service 使用
  bootstrap: [AppComponent],
})

需要注意的地方是 providers 一定要把 service 元件註冊到 module 中,不然後續要相依性注入的時候會不能進行。

相依性注入 service

註冊完 service 後,最重要的就是要注入 service,因為為了就是要共用其行為與邏輯。

feature.service.ts

假設在 service 裡面寫一個方法叫做 run()

export class FeatureService {
  constructor() {}

  run() {
    console.log("featureService");
  }
}

home.component.ts

  1. featureService 注入到 home.component.ts 中,因為註冊到父層就可以讓子層的 home1 跟 home2 元件使用。

  2. 首先在 constructor 建構式裡面宣告一個變數,這邊設定為 featureSvc,透過 TS 宣告型別為 featureService,在完成的過程中,import 也會自動完成。

  3. constructor 上宣告一個 featureService 的屬性。

  4. 如果注入成功後,featureSvc 其屬性的值,就是 featureSvc 本身。

import { FeatureService } from './../feature.service';

export class HomeComponent implements OnInit {
  featureSvc: FeatureService;
  constructor(featureSvc: FeatureService) {
    this.featureSvc = featureSvc;
  }

當注入 featureService 時,透過建構式已經製作了一個實體物件,而且只會建構一次,所以得到的是唯一且可以共用的實體元件,所以未來需要共用的資料或是程式邏輯,都可以透過此元件來共享。

上方可看到要透過三行程式碼才能做出一個 featureService 的建構方式,但在 TS 有更簡潔的寫法,也就是加上其物件是否作為公開或是私有的方法,可改寫成下方這樣,

export class HomeComponent implements OnInit {
  constructor(public featureSvc: FeatureService) {}// 一行解決

  ngOnInit(): void {}
}
  • public: 公開方法,任何程式碼都可以取用。
  • private: 私有方法,只限於其物件下使用。
export class HomeComponent implements OnInit {
  constructor(public featureSvc: FeatureService) {}// 一行解決

  ngOnInit(): void {}
}

透過 ngOnInit() 為例,要使用在 service 建立的方法會變這樣寫:

export class HomeComponent implements OnInit {
  constructor(public featureSvc: FeatureService) {}// 一行解決

  ngOnInit(): void {
    this.featureSvc.run(); // 呼叫在 service 建立的方法
  }
}

featureService

可以看到方法已經從 feature.service.ts 被呼叫了!


上一篇
Angular - 從零開始 - Day7 -Router 路由基礎認識
下一篇
Angular - 從零開始 - Day9 -實作一個側欄選單與 SPA 頁面
系列文
Angular - 從零開始25
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
tso1158687
iT邦新手 1 級 ‧ 2020-09-22 12:21:59

以feature service為例,建立的時候 Angular CLI會預設

@Injectable({
  providedIn: "root",
})

也就是宣告這個service預設的層級在整個應用程式。Angular會自動幫你實例化並且幫你注入。不需要在providers的地方再宣告一次。除非你手動把這個預設的層級拿掉,想要只應用在某個模組之下

Tim Hsu iT邦新手 1 級 ‧ 2020-09-23 11:12:25 檢舉

好的,感謝分享~

我要留言

立即登入留言