前言
之前介紹服務元件的時候就已經看過 @Injectable() 但那個時候並沒有詳加著墨介紹,究竟 @Injectable() 是什麼意思呢?
@Injectable()
Injectable 本身是一個裝飾器 (Decorator) ,主要目的是用於描述這個類別 (class) 是否可以被注入其他的服務元件,事實上如果把之前服務元件上寫的 @Injectable() 刪除,還是可以成功地注入其他元件上,舉例來說:
1 | import { Injectable } from '@angular/core'; |
刪除 @Injectable()
後功能依然正常,也就是說移除裝飾器後,服務元件依然有被注入成功。
既然可以被移除又何必要寫 @Injectable()
因為它可以注入一些額外其它的服務元件,什麼意思呢?
我們可以透過 @Injectable() 注入 HTTP Client 的元件,從伺服器取得動態的資料。
注入服務元件 HTTP Client
在 Angular 中有內建一個服務元件 HTTP Client ,所以先將其注入目前的 Data Service 中。
- 值得一提的是這裡的自動完成匯入的路徑並不是我們要的,應修正為:
import { HttpClient } from '@angular/common/http';
這才是正確的 HTTP 模組來源
1 | import { Injectable } from '@angular/core'; |
處理完之後,這個 httpClient 注入還是失敗的,因為還沒將它加入到 ArticleModule 下。
錯誤訊息說明了必須匯入 HttpClientModule 到 ArticleModule
此時網頁又可以正常運作了
前面有提到如果把 @Injectable()
刪除不影響程式運作,但此時如果直接將 @Injectable()
移除可是會出錯的。
意思是無法解析 DataService 內所有的參數,雖然不太懂是什麼意思,但如果看到 resolve 通常是跟相依注入有關。
因為此時相依注入是從建構式內找到一個 httpClient 參數,然後參數標註 HttpClient 型別
- 所以它必須解析 httpClient 的內容從何而來
- 此時 Angular 會去找出 HttpClient 並且將其 new 出來成為一個物件實體
- 再把這個物件實體丟給 httpClient 參數,然後就解析完成 (resolve 就是這個意思)
- 此時 Angular 會去找出 HttpClient 並且將其 new 出來成為一個物件實體
當透過 Angular CLI 建立服務元件時,預設都會自動加入 @Injectable()
,建議還是不要把它胡亂移除比較好。
於是 HttpClient 服務元件就注入完成了!
如何使用 HttpClient 服務元件
目前文章資料都是寫死的,可以透過 HttpClient 服務元件當中的 get() 方法,動態的取得伺服器上的文章資料。
詳細的 http.get() 方法可以參考官網
而這邊要注意的是 Ajax 的操作在瀏覽器內是非同步的,因此沒辦法在建構式內直接回傳取得的結果
- 在 Angular 內則是透過 Rxjs 幫忙訂閱 http.get() 資料的結果
- 而這個 .get() 的資料類型是 Observable 物件 (觀察者物件)
- 所有的 Observable 物件都必須透過 .subscribe() 方法來訂閱結果
關於 HttpClient 使用方式可以參考這篇 - HttpClient 功能介紹
- 所有的 Observable 物件都必須透過 .subscribe() 方法來訂閱結果
- 而這個 .get() 的資料類型是 Observable 物件 (觀察者物件)
1 | import { Injectable } from '@angular/core'; |
透過 HttpClient 服務元件,正確的接收到資料了!