iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 22
0
Modern Web

Angular 大師之路系列 第 22

[Angular 大師之路] Day 22 - 各種在程式中取的注入 token 實體的方法

前兩天我們學到了多種替換注入 token 內容的方法,今天我們來看看如何取得不同注入內容的方式:

類型:觀念

難度:4 顆星

實用度:3 顆星

建構式注入

建構式注入是我們最常使用的注入方式,也就是直接在建構式中宣告要注入的 token 實體,Angular 在看到這個 token 時,會根據我們的設定決定要對這個類別注入什麼樣的實體:

constructor(private dataService: DataService) { }

在建構式中宣告 private 是 TypeScript 提供的一種語法糖,以上的寫法相當於:

private dataService: DataService;

constructor(dataService: DataService) {
    this.dataService = dataService;
}

透過這種方式,可以少寫一些程式碼,會比較簡單。

使用 Injector

Angular 提供了一個 Injector ,透過其中的 get() 方法,可以幫助我們動態取得某個 token 的實體:

import { Injector } from '@angular/core';

constructor(private injector: Injector) {
  const service = this.injector.get(DataService);
  console.log(service.getData());
}

在元件越來越複雜,建構式要注入的內容越來越多時,使用 Injector ,透過 Injector 可以讓建構是看起來清爽一點!

當然,最理想的情況應該是把原件再拆開成更小的元件,所以這只是提供另外一種思考方向囉。

Injector 還提供了一個 create() 的靜態方法,透過這個方法,我們可以在程式中隨時動態產生一個新的 Injector 物件:

const injector = Injector.create({
  providers: [
    {
      provide: DataService,
      useClass: AdminService,
      deps: []
    }
  ]
});
const service = injector.get(DataService);
console.log(service.getData());

上面程式中,我們使用 Injector.create() 方法,來產生一個 Injector 物件,建立的參數跟在 @NgModule 中設定基本上一樣,但沒有簡易版的寫法,這點需要注意一下。接著我們就能夠這個物件的 get() 方法來取得 token 實體囉。

在 Component 或 Directive 產生獨立實體

@Component@Directive 中,都有提供 providers: [] 的設定,在這裡面設定的 token 會被另外產生,而不會吃所屬模組的設定:

@Component({
  ...
  providers: [
    {
      provide: DataService,
      useClass: AdminService
    }
  ]
})
export class AppComponent  {
  constructor(private dataService: DataService) {
    console.log(dataService.getData());
  }
}

透過這種方式,我們可以確保每次產生元件時都會建立新的實體,而不跟外部產生的實體共享資源!畢竟不是每個元件都需要 singleton 的!

相關資源


上一篇
[Angular 大師之路] Day 21 - 在 @NgModule 的 providers: [] 自由更換注入內容 (2)
下一篇
[Angular 大師之路] Day 23 - 認識 InjectionToken
系列文
Angular 大師之路30

1 則留言

0
He.Chun
iT邦新手 5 級 ‧ 2018-11-21 18:17:09

不好意思
額外想問一下,有關 provider / injector / service 這三者的關係
是 provider 還是 injector 產生 service 的呢 ??
另外將 service 注入到 component 的是 provider 還是 injector ??

抱歉,不知道我有沒有表達好,因為這三個的主從關係或是誰管理誰的關係,一直沒有說搞很懂 > </images/emoticon/emoticon06.gif

這樣解釋看看能不能讓您比較清楚:

  1. providers: [] 是用來設定注入資訊的
  2. 這些注入資訊會存放在一個全域的服務,也就是 injector
  3. injector 是注入資訊的載體,因此我們可以使用 injector.get() 方法取得某個可以被注入的實體
  4. service 單純的是程式,只是他們的概念和實作都被設計成「可以被注入」的

反過來解釋的話:

當然不是只有 service 可以被注入,太多東西都可以被注入了,這部分可以參考上兩篇文章說明如何設定要注入的內容

至於怎麼決定要注入什麼呢?就是 providers: [] 要負責設定的

至於要怎麼注入呢?就是今天文章的重點,除了最常用的建構式注入外,使用 injector 也是其中的一種方法

希望這樣解釋對您的釐清會有幫助,如果還是覺得哪裡有問題,歡迎隨時提出 :)

/images/emoticon/emoticon08.gif

He.Chun iT邦新手 5 級‧ 2018-11-22 13:35:01 檢舉

感謝您!!! 上述的思路很清晰,讓我很好地了解與吸收^^
感覺又多懂了一些東西 /images/emoticon/emoticon32.gif

我要留言

立即登入留言