2016-06-07 47 views
2

中的數組,我們可能有一個不尋常的angular2體系結構,我們在單個頁面上引導多個組件(小部件),而不是處理所有內容的單個應用程序組件。Angular2 Bootstrap Providers vs首先提供組件

我的第一個問題是,以下兩種實現方式是否相同,從我的理解,他們是(請糾正我,如果我誤解的東西):

bootstrap(SomeComponent, [HTTP_PROVIDER, FooService, ServiceNeededByFoo]) 

這初始化SomeComponent並提出了提供者那裏的三項服務。這樣SomeComponent就可以在它自己的構造函數中解析FooService,並且FooService可以解析ServiceNeededByFoo,因爲它在SomeComponent(父類)中查找它。從我的理解這應該是完全一樣的,FooService接口和ServiceNeededByFoo一個新的實例

bootstrap(SomeComponent) 

所以:

如果我定義

providers: [HTTP_PROVIDER, FooService, ServiceNeededByFoo] 

內SomeComponent,我可以像這樣初始化在SomeComponent級別創建並與SomeComponent的所有子節點共享,這些子節點也需要FooService。如果相同,是否有任何優先/推薦的方式?

第二個問題就是現在,我怎麼可以在不在同一個層次DI組件共享FooService接口的單一實例:

bootstrap(SomeComponent1, FooService) 
bootstrap(SomeComponent2, FooService) 

其中FooService接口應該是相同的實例。喜歡的東西:

var foo = new FooService(); 
foo.expensiveInit(); 
bootstrap(SomeComponent1, provide(FooService, {instance: foo})) 
bootstrap(SomeComponent2, provide(FooService, {instance: foo})) 

回答

1

僅供參考,如果有人絆倒在這個帖子,也有一些問題,共享的情況下,當沒有中心的應用程序組件。

我的最終實現是這樣的,它與需要注射服務本身就是一個簡單的服務的服務爲例:

var cs = new ConfigurationService(); 
var injector = ReflectiveInjector.resolveAndCreate([TranslateService, provide(TranslateLoader, {useClass: JsonLoader}), HTTP_PROVIDERS]); 
var ts = injector.get(TranslateService); 

ts.setDefaultLang('en'); 
ts.use(cs.getLanguage()); 

var defaultProviders = [provide(TranslateService, {useValue: ts}), provide(ConfigurationService, {useValue: cs})]; 

if ($('notification-widget').length > 0) { 
    bootstrap(NotificationWidgetComponent, defaultProviders); 
} 

if ($('livesearch-widget').length > 0){ 
    bootstrap(LivesearchWidgetComponent, defaultProviders); 
} 
+0

提供mehods和Provider類現在是rc3的depricates,我還沒有找到替換,因爲代碼中的註釋簡單地說「TODO:improve docs」 – Tom

2

角DI產生根源在哪裏被bootstrap()創建和供應商傳遞給bootstrap()噴油器的層次結構。
默認由角提供的所有東西被添加到該噴射器以及(如PLATFORM_PIPESPLATFORM_DIRECTIVES,...)

然後從根組件的子注入與在根組件提供的供應商開始創建。對於每個子組件和根組件指令,都會創建子注入器,直至葉子組件和指令。

噴油器層次結構因此類似於您的組件和指令層次結構。

當組件需要依賴項(構造函數參數)時,DI在它的注入器提供程序上查找它。如果找不到它,它會檢查父噴嘴,然後繼續執行由bootstrap()創建的根噴嘴。

這應該很清楚地表明bootstrap()的提供者或根組件的提供者導致了完全相同的行爲。

您分享兩個獨立的自舉部件之間的服務方式似乎沒什麼問題,但據我所知,應該是useValue代替instance

bootstrap(SomeComponent1, provide(FooService, {useValue: foo})) 

參見

如上所述,如果您使用observabl發出值e在共享服務中,值將在發件人區域中發出,而其他應用程序中的訂閱者在發件人區域中被調用。確保您使用zone.run

constructor(sharedService:FooService, zone:NgZone) { 
    sharedService.someObservable.subscribe(value => { 
    zone.run(() => { 
     this.data = value; 
     this.router.navigate... 
     ... 
    }); 
    }); 
} 
+0

感謝詳盡的解釋!特別是最後的例子。 – Tom