Angular 4 依賴注入學(xué)習(xí)教程之FactoryProvider的使用(四)
學(xué)習(xí)目錄
- Angular 4 依賴注入教程之一 依賴注入簡介
- Angular 4 依賴注入教程之二 組件服務(wù)注入
- Angular 4 依賴注入教程之三 ClassProvider的使用
- Angular 4 依賴注入教程之四 FactoryProvider的使用
- Angular 4 依賴注入教程之五 FactoryProvider配置依賴對象
- Angular 4 依賴注入教程之六 Injectable 裝飾器
- Angular 4 依賴注入教程之七 ValueProvider的使用
- Angular 4 依賴注入教程之八 InjectToken的使用
前言
本文屬于Angular 4 依賴注入學(xué)習(xí)系列的第四篇,主要介紹了Angular 4 依賴注入之FactoryProvider的使用,感興趣的朋友們下面來看看詳細(xì)的介紹:
本系列教程的開發(fā)環(huán)境及開發(fā)語言:
基礎(chǔ)知識
FactoryProvider 的作用
FactoryProvider 用于告訴 Injector (注入器),通過調(diào)用 useFactory 對應(yīng)的函數(shù),返回 Token 對應(yīng)的依賴對象。
FactoryProvider 的使用
function serviceFactory() {
return new Service();
}
const provider: FactoryProvider = {
provide: 'someToken', useFactory: serviceFactory, deps: []
};
FactoryProvider 接口
export interface FactoryProvider {
// 用于設(shè)置與依賴對象關(guān)聯(lián)的Token值,Token值可能是Type、InjectionToken、
// OpaqueToken的實(shí)例或字符串
provide: any;
// 設(shè)置用于創(chuàng)建對象的工廠函數(shù)
useFactory: Function;
// 依賴對象列表
deps?: any[];
// 用于標(biāo)識是否multiple providers,若是multiple類型,則返回與Token關(guān)聯(lián)的依賴
// 對象列表
multi?: boolean;
}
FactoryProvider
介紹完基礎(chǔ)知識,接下來我們馬上進(jìn)入正題。不知道大家是否還記得,之前我們創(chuàng)建過的 HeroComponent 組件:
import { Component, OnInit } from '@angular/core';
import { HeroService } from '../hero.service';
@Component({
selector: 'app-hero',
template: `
<ul>
<li *ngFor="let hero of heros">
ID: {{hero.id}} - Name: {{hero.name}}
</li>
</ul>
`
})
export class HeroComponent implements OnInit {
constructor(private heroService: HeroService) { }
heros: Array<{ id: number; name: string }>;
ngOnInit() {
this.heros = this.heroService.getHeros();
}
}
那么現(xiàn)在問題來了,假設(shè)我們想在獲取英雄數(shù)據(jù)時(shí),輸出調(diào)試信息,那應(yīng)該怎么辦?What ~,這個(gè)問題不是很簡單么,直接使用 console.log API 輸出相應(yīng)信息不就行了么:
console.log('Fetching heros...');
this.heros = this.heroService.getHeros();
那問題又來了,如果多個(gè)組件都使用 HeroService 去獲取英雄數(shù)據(jù),那么是不是每個(gè)組件都得添加對應(yīng)的語句。另外如果要修改輸出的調(diào)試信息,那就得修改程序中多個(gè)地方。其實(shí)我們一般只需要在開發(fā)階段,輸出調(diào)試信息,因此上面的方案不合理,也不夠靈活。
其實(shí)我們可以借鑒之前引入 HeroService 服務(wù)的思路,創(chuàng)建一個(gè) LoggerService 來解決上面提到的問題。
創(chuàng)建 LoggerService 服務(wù)
export class LoggerService {
constructor(private enable: boolean) { }
log(message: string) {
if(this.enable) {
console.log(`LoggerService: ${message}`);
}
}
}
配置 LoggerService 服務(wù)
@NgModule({
...
providers: [
HeroService,
LoggerService
],
bootstrap: [AppComponent]
})
export class AppModule { }
使用 LoggerService 服務(wù)
import { Component, OnInit } from '@angular/core';
import { HeroService } from '../hero.service';
import { LoggerService } from './../logger.service';
@Component({
selector: 'app-hero',
template: `
<ul>
<li *ngFor="let hero of heros">
ID: {{hero.id}} - Name: {{hero.name}}
</li>
</ul>
`
})
export class HeroComponent implements OnInit {
heros: Array<{ id: number; name: string }>;
constructor(private heroService: HeroService,
private loggerService: LoggerService) { }
ngOnInit() {
this.loggerService.log('Fetching heros...');
this.heros = this.heroService.getHeros();
}
}
以上代碼運(yùn)行后會(huì)拋出以下異常信息:
Uncaught Error: Can't resolve all parameters for LoggerService: (?).
有的讀者,眼睛一亮,可能是你在創(chuàng)建 LoggerService 服務(wù)時(shí),忘記使用 @Injectable 裝飾器了。哈哈,其實(shí)我是故意的,但我加上 @Injectable() 后,還是拋出了以下異常:
ERROR Error: No provider for Boolean!
為什么會(huì)出現(xiàn)上面的異常信息呢?我們再看一下前面創(chuàng)建的 LoggerService 服務(wù):
export class LoggerService {
constructor(private enable: boolean) { }
// ...
}
在 Angular 中我們通過構(gòu)造注入的方式注入依賴對象, private enable: boolean 這種方式表示我們要注入 Type 類型的對象。然后 boolean 是表示基本數(shù)據(jù)類型,并不是所需的 Type 類型:
export function isType(v: any): v is Type<any> {
return typeof v === 'function';
}
接下來我們再來看一下最早拋出的異常:
Uncaught Error: Can't resolve all parameters for LoggerService: (?).
其實(shí)問題的答應(yīng)也在 LoggerService 類的構(gòu)造函數(shù)中,在創(chuàng)建 LoggerService 對象時(shí),我們需要設(shè)置 enable 參數(shù)的值。那么如何解決呢? 當(dāng)然可以使用我們的主角 - FactoryProvider 。
具體如下:
使用 FactoryProvider
@NgModule({
...,
providers: [
HeroService,
{
provide: LoggerService,
useFactory: () => {
return new LoggerService(true);
}
}
],
bootstrap: [AppComponent]
})
export class AppModule { }
當(dāng)更新完代碼,然后再來一個(gè)華麗的保存操作,最后打開你的控制臺,你將看到預(yù)期的輸出信息:
LoggerService: Fetching heros...
難道就這樣結(jié)束了,關(guān)于 FactoryProvider 的相關(guān)內(nèi)容先告一段落,下一篇我們將介紹如何使用 FactoryProvider 配置依賴對象。
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者使用Angular 4能帶來一定的幫助,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。
- Angular 4依賴注入學(xué)習(xí)教程之InjectToken的使用(八)
- Angular 4依賴注入學(xué)習(xí)教程之ValueProvider的使用(七)
- Angular 4依賴注入學(xué)習(xí)教程之Injectable裝飾器(六)
- Angular 4依賴注入學(xué)習(xí)教程之FactoryProvider配置依賴對象(五)
- Angular 4依賴注入學(xué)習(xí)教程之ClassProvider的使用(三)
- Angular 4依賴注入學(xué)習(xí)教程之組件服務(wù)注入(二)
- Angular 4依賴注入學(xué)習(xí)教程之簡介(一)
- 深入理解Angular4中的依賴注入
相關(guān)文章
Angular中實(shí)現(xiàn)樹形結(jié)構(gòu)視圖實(shí)例代碼
近兩年當(dāng)中使用Angular開發(fā)過很多項(xiàng)目,其中也涉及到一些樹形結(jié)構(gòu)視圖的顯示,最近的在項(xiàng)目中封裝了大量的組件,一些組件也有樹形結(jié)構(gòu)的展示,所以寫出來總結(jié)一下。2017-05-05
AngularJS實(shí)現(xiàn)的獲取焦點(diǎn)及失去焦點(diǎn)時(shí)的表單驗(yàn)證功能示例
這篇文章主要介紹了AngularJS實(shí)現(xiàn)的獲取焦點(diǎn)及失去焦點(diǎn)時(shí)的表單驗(yàn)證功能,涉及AngularJS使用ng-blur、ng-focus針對表單事件監(jiān)聽相關(guān)操作技巧,需要的朋友可以參考下2017-10-10
AngularJS實(shí)現(xiàn)圖片上傳和預(yù)覽功能的方法分析
這篇文章主要介紹了AngularJS實(shí)現(xiàn)圖片上傳和預(yù)覽功能的方法,結(jié)合HTML5實(shí)例形式對比分析了AngularJS圖片上傳的相關(guān)操作技巧與注意事項(xiàng),需要的朋友可以參考下2017-11-11
AngularJS2 與 D3.js集成實(shí)現(xiàn)自定義可視化的方法
本篇文章主要介紹了ANGULAR2 與 D3.js集成實(shí)現(xiàn)自定義可視化的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-12-12
AngularJS實(shí)現(xiàn)進(jìn)度條功能示例
這篇文章主要介紹了AngularJS實(shí)現(xiàn)進(jìn)度條功能,結(jié)合具體完整實(shí)例形式分析了AngularJS實(shí)現(xiàn)進(jìn)度條功能的原理、相關(guān)知識點(diǎn)與注意事項(xiàng),需要的朋友可以參考下2017-07-07
使用Angular 6創(chuàng)建各種動(dòng)畫效果的方法
Angular能夠讓我們創(chuàng)建出具有原生表現(xiàn)效果的動(dòng)畫。我們將通過本文學(xué)習(xí)到如何使用Angular 6來創(chuàng)建各種動(dòng)畫效果。在此,我們將使用Visual Studio Code來進(jìn)行示例演示。感興趣的朋友跟隨小編一起看看吧2018-10-10

