iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 18
1

在開發元件的時候,我們會希望元件間的相依性不要太高,否則當專案越來越大時,修改一個小地方,就會有一連串元件都受影響,牽一髮而動全身。

所以我們會希望,將一些功能獨立出來,寫成 Service,再將這個 Service 注入到個別的元件裡,降低元件間彼此的相依性。並且因為這樣的方式,未來若需要抽換 Service,也比較不費力。

這邊的方法叫依賴注入(Dependency Injection),簡稱 DI,是一種降低相依性的設計模式。簡單來講,就是把一些自己做的事情,交給第三方,第三方再透過注入的方式,把手伸進來幫你做事。

那依照慣例,我們先用 Angular-CLI 建立一個 service:

ng generate service <service name>
ng g s <service name>

然後你會發現這次 Angular-CLI 沒有去改動 module.ts 的檔案了,((沒甚麼了不起的


我創建一個叫 http 的 Service,將來要透過它來 call 各種 Web API:

初始的 service.ts 會有一個 @Injectable 的 Decorator,並且幫我們填入了 providedIn: 'root',這表示當有任何一個元件,調用這個 Service 時,Angular 會去 root injector 找看看有沒有這個 Service 的實體,如果沒有,就創建一個實體,並放在 root injector。

往後其他元件要調用這個 Service,就會到 root injector 去找,並且使用。所以整個程式只會有一個 Service 的實體,裡面的變數、 function 都是共用的。

那如果你不想要讓整個程式都使用這個 Service,或是有其他的考量,可以把它拿掉,然後到 Module 裡把剛剛的 Service 加到 providers 裡:

// http.service.ts

@Injectable()
export class HttpService {
    ...
}
// account.module.ts

import { HttpService } from './http.service';

@NgModule({
    ...
    providers: [HttpService]

})

這樣一來,同一個 module 下的元件,在調用 HttpService 時就會取得同一個實體。
現在我們可以在 Service 裡寫一些程式碼了:

export class HttpService {

 display() {
     alert('Alert from HttpService.');
  }
}

接下來我想在其他元件也調用這個 function,我們到 login.component.ts,將這個服務注入。

我們新增一個成員變數叫 http,並在 constructor() 內初始化。由於我們剛剛有把 HttpService 註冊進 account.module.tsproviders 中,所以在初始化這個元件時,會自動完成「到 injector 找 Service 實體」的這段動作。

 private http: HttpService;
 constructor(httpService: HttpService) {
     this.http = httpService;
  }

也可以只寫這樣的語法,這樣在 constructor() 時,會自動產生一個成員變數叫 http

constructor(private http: HttpService) {  }

在完成注入後,如果你的 @Injectable() 沒有設定 providedIn: 'root',也沒有把 Service 放到該放的 providers 中。那執行 constructor() 時就會噴一堆 Error:

現在 LoginComponent 已經被注入了 HttpService,這表示我們可以去調用 HttpService 的 function 了。
於是我不小心在 loginAction() 加入了 HttpServicedisplay()

loginAction() {
    this.loginRequest.emit(true);
    this.http.display();
 }

點下 Login 時,就可以調用 HttpServicedisplay()

如此我們就完成了一個簡單的 Service 實作。


上一篇
# DAY 17 @Output
下一篇
# DAY 19 表單
系列文
從零開始的Angular前端開發30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言