0%

Angular 筆記 - Service 服務元件的基本認識

angular

什麼服務元件

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

建立服務元件

本次範例

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

app

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

1
ng g s 元件名稱

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

feature

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

1
2
3
4
5
6
7
8
import { Injectable } from "@angular/core";

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

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

注入 service

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

1
2
3
4
5
6
7
8
9
10
11
12
@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 就可以完成囉!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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()

1
2
3
4
5
6
7
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 本身。

1
2
3
4
5
6
7
import { FeatureService } from './../feature.service';

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

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

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

1
2
3
4
5
export class HomeComponent implements OnInit {
constructor(public featureSvc: FeatureService) {}// 一行解決

ngOnInit(): void {}
}
  • public: 公開方法,任何程式碼都可以取用。
  • private: 私有方法,只限於其物件下使用。

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

1
2
3
4
5
6
7
export class HomeComponent implements OnInit {
constructor(public featureSvc: FeatureService) {}// 一行解決

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

featureService

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