2016-07-31 153 views
4

從我的理解,你可以在你的引導呼叫定義應用程序供應商是這樣的:Angular2提供商自舉VS @Component

bootstrap(
    App, 
    [disableDeprecatedForms(), provideForms()]] 
) 

或在你的根組件是這樣的:

@Component({ 
    selector: 'my-app', 
    providers: [disableDeprecatedForms(), provideForms()], 
    ... 
) 

然而,我創建了一個需要提供表單提供者的表單驗證器插件,並且此引導僅在引導選項時起作用。我創建了一個plunk to illstrate the problem:如果將providerForms()添加到引導程序調用,則驗證程序將起作用。只要我從bootstrap調用註釋掉providerForms(),驗證器就不再工作。我認爲組件中的providerForms定義是足夠的。任何解釋?

+0

運行時編譯器在將提供程序注入AppComponent之前創建。這種方式編譯器使用舊的窗體類到AppComponent.template.js中。 AppComponent的提供者中的方法'useFactory'僅在將令牌插入構造函數時觸發。 https://plnkr.co/edit/Ed8ao38phPNsYeHMorcg?p=preview – yurzui

回答

3

Angular2 DI總是向上查找請求依賴項的提供者。如果一個由bootstrap實例化的服務需要一個依賴關係,那麼它不會得到一個被注入的東西,而這個東西是在樹的下面提供的。

在根組件提供的bootstrap(...)@Component(...)並不等同,但是這種區別與根組件或其子組件或其子組件中的所有內容無關。 bootstrap()比根組件高一級。

Angular2風格指南還建議優先選擇bootstrap()以上的根組件,因爲bootstrap應該保留給系統的東西。

形式和路由器需要創建第一組件之前被實例化(有例如在根組件需要注入Router或含有routerLink的V3路由器的早期版本中的錯誤,否則該路由器止跌」 t啓動)。

因此,因爲有些事情需要在創建根組件之前實例化,所以出現bootstrap()與根組件之間的差異變得相關的情況。

+0

您是否瞭解這些提供商的哪一部分負責此行爲?在確定提供者是否符合非根注射器的條件時,我們應該尋找什麼?我希望我們在A1中保留了配置/運行歧視,但看起來都一樣。 – estus

+0

不確定你的意思是「哪個部分」。我只知道在Angular2 GitHub的問題中提到'provideRouter()'需要在'bootstrap()'中使用,而不是根組件。我並不驚訝'disableDeprecatedForms()'和'provideForms()'需要相同的內容,但我不知道爲什麼。 –

+0

你能提供一個鏈接到提到的github問題嗎? – schacki