前言
用得好好的為啥要重構呢?原因是目前這個 DataService 並沒有寫得很漂亮,原因是通常不會直接在服務元件內直接做 .subscribe() 的動作,大部分的情況都是在其他元件內進行。畢竟什麼時候要訂閱是各個元件自己才知道,服務元件單純的提供服務就好。
重構 DataService
移除先前為了介紹寫在建構式內的程式碼,並且新增一個方法叫 getData()
- httpClient.get() 方法會最後會產生一個觀察者物件,將其回傳
- 而這麼做,意味著資料最後不會出現在服務元件內,因此先註解其他程式碼
1 | import { Injectable } from '@angular/core'; |
調整 ArticleList 元件
因為先前的調整,ArticleList 內幾乎已經沒有程式碼了,原因是該元件的 Tamplate 內是直接讀取 DataService 的資料。
但現在 DataService 已經沒有 atticleData
屬性了,怎麼辦呢?
解決辦法:
- 呼叫 DataService 內的 getData 方法
- 因為這個方法將回傳一個觀察者物件 (Observable Object),因此可以使用 .subscribe() 方法
- 成功取得資料後,將資料賦值給
atticleData
屬性- 因為之前把元件內的
atticleData
屬性移除了,現在必須加回去
- 因為之前把元件內的
- 成功取得資料後,將資料賦值給
- 因為這個方法將回傳一個觀察者物件 (Observable Object),因此可以使用 .subscribe() 方法
1 | import { Component, OnInit } from '@angular/core'; |
這樣看起來就合理多了,應該是由元件來決定何時訂閱,而不是由服務元件來決定。
因為可能會有多種不同的事件來處發 API ,所以由個別元件來決定是最合理的。
調整完後還有 Template 要修改:
- 目前資料已經透過訂閱回到 ArticleList 本身了
也因為資料已經在自身元件,所以刪除與改標題的方法也必須移動回元件本身。
1 | <!-- Article START--> |
最終 ArticleList 是這樣的:
1 | import { Component, OnInit } from '@angular/core'; |
重新整理一下想法:
- 目前 ArticleList 透過服務元件上的 getData() 方法取得 文章資料
- 而現在的資料都是來自於 Server 端,我們只是把 Server 端的資料抓下來暫存在 atticleData 屬性而已
- 因此 doDelete() 、 doModify() 都是修改存放在 local 端的資料,並不是真正修改 Server 端的資料
也就是說需要回到 DataService 上調整 doDelete() 、 doModify() 這兩個方法。
調整 DataService 服務元件
doDelete()
- 使用 httpClient.delete() 發送一個 delete 請求給伺服器刪除特定資料,並帶上文章 id
doModify()
- 使用 httpClient.put() 發送一個 put 請求給伺服器更新特定資料,並帶上文章 id
- 第二個參數則傳入
post
, httpClient 會自動把post
這個物件轉換成 json 格式
- 第二個參數則傳入
1 | import { Injectable } from '@angular/core'; |
至此 DataService 就調整完畢了,最後再次回到 ArticleList 元件完成真正的刪除與修改!
觸發 DataService 上的 doDelete() 及 doModify()
用法是這樣的:
- 當 ArticleList 元件內的 doDelete() 被觸發時
- 呼叫 DataService 上的 doDelete() 並傳入
item
並且訂閱結果- 當結果成立時 (伺服器端的資料被刪除了) 才執行 local 端的資料刪除
- 呼叫 DataService 上的 doDelete() 並傳入
同理 doModify() 也是。
另外,串接 API 時常常會遇到一些意外的狀況,此時
- 可以用上 .subscribe() 第二個參數 error ,同樣也是個 callback function
- 可以透過這個 callback 取得錯誤的結果
1 | import { Component, OnInit } from '@angular/core'; |
大功告成,來試試看吧!
一切都符合我們的預期 :D