這次帶給大家在Angular裡ViewProviders和Providers的差別,在Angular裡使用ViewProviders和Providers的注意事項有哪些,下面就是實戰案例,一起來看一下。
在Angular中使用依賴注入(DI)的時候,我們一般會使用providers
。其實要做同樣的事我們還有另一個選擇:viewProviders
。
viewProviders
允許我們定義只對元件的view可見的provider。下面我們用例子詳細的說明這一點。
假設我們有一個簡單的服務:
// myService.service.ts import { Injectable } from '@angular/core'; @Injectable() export class MyService{ testIfGetService(where){ console.log('Got My Service in ' + where); } }
這個服務很簡單,只需要列印在哪裡呼叫了該服務。
接著有一個子元件,是用來投射到父元件裡面的(等會看到):
// child.component.ts import { Component } from '@angular/core'; import { MyService } from './myService.service'; @Component({ selector: 'vp-child', template: ` <p>This is child!!!</p> ` }) export class VPChild{ constructor( private service: MyService ){ this.service.testIfGetService('child'); } }
這個元件注入了MyService
服務,呼叫MyService
的testIfGetService
方法,並傳入child
表示這是在child元件呼叫的。
還有另外一個子元件,這個元件是用來放在父元件的模板(template)裡面的:
// viewChild.component.ts import { Component } from '@angular/core'; import { MyService } from './myService.service'; @Component({ selector: 'vp-viewchild', template: ` <p>This is viewChild!!!</p> ` }) export class ViewVPChild{ constructor( private service: MyService ){ this.service.testIfGetService('viewChild'); } }
這裡同樣注入MyService
服務,呼叫 MyService
服務的testIfGetService
方法,並傳入viewChild
。
最後是父元件:
// parent.component.ts import { Component } from '@angular/core'; import { MyService } from './myService.service'; @Component({ selector: 'vp-parent', template: ` <p>This is parent!!!</p> <ng-content></ng-content> <vp-viewchild></vp-viewchild> `, providers: [MyService] }) export class VPParent{ constructor( private service: MyService ){ this.service.testIfGetService('parent'); } }
在父元件,用providers
註冊MyService
,然後呼叫MyService
的testIfGetService
傳入parent
。
然後就像這樣使用父元件:
<vp-parent> <vp-child></vp-child> </vp-parent>
運行程序,控制台列印出了結果:
一切就像預期一樣! !
然後,我們用viewProviders
代替providers
註冊MyService
,看看會發生什麼:
// parent.component.ts import { Component } from '@angular/core'; import { MyService } from './myService.service'; @Component({ selector: 'vp-parent', template: ` <p>This is parent!!!</p> <ng-content></ng-content> <vp-viewchild></vp-viewchild> `, viewProviders: [MyService] // <--- }) export class VPParent{ constructor( private service: MyService ){ this.service.testIfGetService('parent'); } }
這樣修改之後,執行程序,發現報錯了:
如果把contentChild註解掉,就像這樣:
<vp-parent> <!-- <vp-child></vp-child> --> </vp-parent>
是不會報錯的:
這就說明,在父元件用viewProviders
註冊的provider,對contentChildren是不可見的。而使用providers
註冊的provider,對viewChildren和contentChildren都可見!
補充說明:元件會逐級向上尋找provider,直到找到為止,否則就會拋出錯誤。就像這裡:
<vp-parent> <vp-child></vp-child> </vp-parent>
vp-child
往上找MyService
的provider,結果在vp-parent
找到了。但在用viewProviders
的時候,vp-child
往上找,也就是到vp-parent
,結果沒找到,然後又去找 vp-parent
的父級,還是沒找到(因為在這個例子裡,我們只在vp-parent
註冊了MyService
),然後又繼續往上找… ……如此找到邊界也沒找到,所以拋出了一個錯誤。如果你不希望這樣,可以使用@Host
做出限制,就像這樣:
constructor( @Host() private service: MyService ){}
關於@Host()本文不作展開,有興趣可以自行google。
相信看了本文案例你已經掌握了方法,更多精彩請關注php中文網其它相關文章!
推薦閱讀:
以上是在Angular裡ViewProviders和Providers的區別的詳細內容。更多資訊請關注PHP中文網其他相關文章!