W3Cschool
恭喜您成為首批注冊(cè)用戶(hù)
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
服務(wù)是一個(gè)廣義的概念,它包括應(yīng)用所需的任何值、函數(shù)或特性。狹義的服務(wù)是一個(gè)明確定義了用途的類(lèi)。它應(yīng)該做,并做好一些具體的事。
Angular 把組件和服務(wù)區(qū)分開(kāi),以提高模塊性和復(fù)用性。 通過(guò)把組件中和視圖有關(guān)的功能與其它類(lèi)型的處理分離開(kāi),你可以讓組件類(lèi)更加精簡(jiǎn)、高效。
理想情況下,組件的工作只管用戶(hù)體驗(yàn),而不用顧及其它。 它應(yīng)該提供用于數(shù)據(jù)綁定的屬性和方法,以便作為視圖(由模板渲染)和應(yīng)用邏輯(通常包含一些模型的概念)的中介者。
組件應(yīng)該把諸如從服務(wù)器獲取數(shù)據(jù)、驗(yàn)證用戶(hù)輸入或直接往控制臺(tái)中寫(xiě)日志等工作委托給各種服務(wù)。通過(guò)把各種處理任務(wù)定義到可注入的服務(wù)類(lèi)中,你可以讓它被任何組件使用。 通過(guò)在不同的環(huán)境中注入同一種服務(wù)的不同提供者,你還可以讓你的應(yīng)用更具適應(yīng)性。
Angular 不會(huì)強(qiáng)迫您遵循這些原則。Angular 只會(huì)通過(guò)依賴(lài)注入來(lái)幫您更容易地將應(yīng)用邏輯分解為服務(wù),并讓這些服務(wù)可用于各個(gè)組件中。
應(yīng)用示例
以下示例,用于將日志記錄到瀏覽器的控制臺(tái)。
export class Logger {
log(msg: any) { console.log(msg); }
error(msg: any) { console.error(msg); }
warn(msg: any) { console.warn(msg); }
}
服務(wù)也可以依賴(lài)其它服務(wù)。比如,這里的 HeroService 就依賴(lài)于 Logger 服務(wù),它還用 BackendService 來(lái)獲取英雄數(shù)據(jù)。BackendService 還可能再轉(zhuǎn)而依賴(lài) HttpClient 服務(wù)來(lái)從服務(wù)器異步獲取英雄列表。
export class HeroService {
private heroes: Hero[] = [];
constructor(
private backend: BackendService,
private logger: Logger) { }
getHeroes() {
this.backend.getAll(Hero).then( (heroes: Hero[]) => {
this.logger.log(`Fetched ${heroes.length} heroes.`);
this.heroes.push(...heroes); // fill cache
});
return this.heroes;
}
}
DI 被融入 Angular 框架中,用于在任何地方給新建的組件提供服務(wù)或所需的其它東西。 組件是服務(wù)的消費(fèi)者,也就是說(shuō),你可以把一個(gè)服務(wù)注入到組件中,讓組件類(lèi)得以訪問(wèn)該服務(wù)類(lèi)。
在 Angular 中,要把一個(gè)類(lèi)定義為服務(wù),就要用 @Injectable()
裝飾器來(lái)提供元數(shù)據(jù),以便讓 Angular 可以把它作為依賴(lài)注入到組件中。 同樣,也要使用 @Injectable()
裝飾器來(lái)表明一個(gè)組件或其它類(lèi)(比如另一個(gè)服務(wù)、管道或 NgModule)擁有一個(gè)依賴(lài)。
你的應(yīng)用中所需的任何依賴(lài),都必須使用該應(yīng)用的注入器來(lái)注冊(cè)一個(gè)提供者,以便注入器可以使用這個(gè)提供者來(lái)創(chuàng)建新實(shí)例。 對(duì)于服務(wù),該提供者通常就是服務(wù)類(lèi)本身。
注:
- 依賴(lài)不一定是服務(wù),它也有可能是函數(shù)或者值。
當(dāng) Angular 創(chuàng)建組件類(lèi)的新實(shí)例時(shí),它會(huì)通過(guò)查看該組件類(lèi)的構(gòu)造函數(shù),來(lái)決定該組件依賴(lài)哪些服務(wù)或其它依賴(lài)項(xiàng)。 比如 HeroListComponent 的構(gòu)造函數(shù)中需要 HeroService:
constructor(private service: HeroService) { }
當(dāng) Angular 發(fā)現(xiàn)某個(gè)組件依賴(lài)某個(gè)服務(wù)時(shí),它會(huì)首先檢查是否該注入器中已經(jīng)有了那個(gè)服務(wù)的任何現(xiàn)有實(shí)例。如果所請(qǐng)求的服務(wù)尚不存在,注入器就會(huì)使用以前注冊(cè)的服務(wù)提供者來(lái)制作一個(gè),并把它加入注入器中,然后把該服務(wù)返回給 Angular。
當(dāng)所有請(qǐng)求的服務(wù)已解析并返回時(shí),Angular 可以用這些服務(wù)實(shí)例為參數(shù),調(diào)用該組件的構(gòu)造函數(shù)。
HeroService 的注入過(guò)程如下所示:
對(duì)于要用到的任何服務(wù),您必須至少注冊(cè)一個(gè)提供者。服務(wù)可以在自己的元數(shù)據(jù)中把自己注冊(cè)為提供者,這樣可以讓自己隨處可用。或者,您也可以為特定的模塊或組件注冊(cè)提供者。要注冊(cè)提供者,就要在服務(wù)的 @Injectable()
裝飾器中提供它的元數(shù)據(jù),或者在 @NgModule()
或 @Component()
的元數(shù)據(jù)中。
@Injectable({
providedIn: 'root',
})
當(dāng)你在根一級(jí)提供服務(wù)時(shí),Angular 會(huì)為 HeroService 創(chuàng)建一個(gè)單一的共享實(shí)例,并且把它注入到任何想要它的類(lèi)中。這種在 @Injectable 元數(shù)據(jù)中注冊(cè)提供者的方式還讓 Angular 能夠通過(guò)移除那些從未被用過(guò)的服務(wù)來(lái)優(yōu)化大小。
@NgModule({
providers: [
BackendService,
Logger
],
...
})
@Component()
元數(shù)據(jù)的 providers 屬性中注冊(cè)服務(wù)提供者。@Component({
selector: 'app-hero-list',
templateUrl: './hero-list.component.html',
providers: [ HeroService ]
})
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: