2016-09-23 3 views
43

Может ли кто-нибудь пояснить мне, как мне структурировать иерархию нескольких вложенных функциональных модулей с вызовами .forRoot()?Как использовать .forRoot() в иерархии функциональных модулей

Например, что если у меня есть такие модули, как это:

- MainModule 
- SharedModule 
- FeatureModuleA 
    - FeatureModuleA1 
    - FeatureModuleA2 
- FeatureModuleB 

Все модули функций имеет .forRoot() статические функции.

Как определить FeatureModuleA с каким-либо образом «передать» функции .forRoot()?

@NgModule({ 
    imports: [ 
    //- I can use .forRoot() calls here but this module not the root module 
    //- I don't need to import sub-modules here, FeatureA only a wrapper 
    //FeatureModuleA1.forRoot(), //WRONG! 
    //FeatureModuleA2.forRoot(), //WRONG! 
    ], 
    exports: [ 
    //I cannot use .forRoot() calls here 
    FeatureModuleA1, 
    FeatureModuleA2 
    ] 
}) 
class FeatureModuleA { 
    static forRoot(): ModuleWithProviders { 
    return { 
     //At this point I can set any other class than FeatureModuleA for root 
     //So lets create a FeatureRootModuleA class: see below! 
     ngModule: FeatureModuleA //should be: FeatureRootModuleA 
    }; 
    } 
} 

я могу создать еще один класс для использования корневой затем установить его в forRoot() функцию FeatureModuleA:

@NgModule({ 
    imports: [ 
    //Still don't need any sub module within this feature module 
    ] 
    exports: [ 
    //Still cannot use .forRoot() calls but still need to export them for root module too: 
    FeatureModuleA1, 
    FeatureModuleA2 
    ] 
}) 
class FeatureRootModuleA { } 

Но как я могу "передача" .forRoot() вызывает в этом специальный ModuleClass?

Как я вижу, что нужно импортировать все суб-модулей непосредственно в мой корневой MainModule и вызвать .forRoot() для каждого есть:

@NgModule({ 
    imports: [ 
    FeatureModuleA1.forRoot(), 
    FeatureModuleA2.forRoot(), 
    FeatureModuleA.forRoot(), 
    SharedModule.forRoot() 
    ] 
}) 
class MainModule { } 

Я прав? Прежде чем ответить, пожалуйста, взгляните на этот файл: https://github.com/angular/material2/blob/master/src/lib/module.ts

Как я знаю, это репо поддерживается официальной угловой командой. Поэтому они решают вышеупомянутое, просто импортируя все вызовы .forRoot() в специальном модуле MaterialRootModule. Я действительно не понимаю, как это будет применяться для моего собственного корневого модуля? Что означает корень и .forRoot действительно означает здесь? Это относительно пакета, а не фактического веб-проекта?

+0

Я не уверен, почему вы хотите создать и использовать метод 'forRoot'. Возможно, это помогает: https://angular.io/docs/ts/latest/guide/ngmodule.html – mxii

+1

Да. Я прочитал официальную документацию. Там нет ничего о том, как структурировать сложные проекты с несколькими вложенными модулями. Я хочу создать и использовать forRoot именно потому, что синглеты провайдеров должны быть установлены только один раз во всем проекте. – ggabor

+0

Хорошо, потому что в вашем примере не было провайдеров. :) – mxii

ответ

79

Обычно forRoot используется для добавления приложений/услуг Singleton.

@NgModule({ 
    providers: [ /* DONT ADD HERE */ ] 
}) 
class SharedModule { 
    static forRoot() { 
    return { 
     ngModule: SharedModule, 
     providers: [ AuthService ] 
    } 
    } 
} 

Полагают, что если добавить AuthService к providers в @NgModule, это возможно для более чем один будет создан, если вы импортировать SharedModule в другие модули.

Я не на 100% не знаю, будет ли служба создана, когда SharedModule импортируется в модуль с высокой нагрузкой, но объяснение, о котором упомянутые документы касалось лениво загружаемых модулей. Когда вы ленивно загружаете модуль, все провайдеры будут созданы.

По этой причине мы добавляем (по соглашению) forRoot метод означает, что метод должен вызываться только для модуля корня (приложение), в то время как для других модулей он просто должен быть импортирован нормально

@NgModule({ 
    imports: [SharedModule] 
}) 
class FeatureModule {} 

@NgModule({ 
    imports: [SharedModule.forRoot()] 
}) 
class AppModule {} 
+0

Благодарим вас за ваши усилия, но это все равно не заботится о многоуровневом корпусе вложенного модуля. В вашем примере вы импортировали AuthService в SharedModule. Не могли бы вы реорганизовать свой пример с импортом SharedModule (модуль вместо службы!) - и попробуйте использовать AuthModule.forRoot() где-нибудь. (отказ от ответственности: для меня AuthService/AuthModule просто пример здесь - это может быть любой модуль с методами forChild и forRoot.) – ggabor

+3

forRoot должен использоваться только для модуля приложения. Не должно быть необходимости пересылать что-либо. Когда вы импортируете Just SharedModule без forRoot, forRoot никогда не вызывается. Мы должны структурировать наши модули таким образом. Службы App-wide в forRoot и все остальное в NgModule. Вложенные или нет, вот как вы должны это учитывать –

+0

Если вам нужно импортировать функциональный модуль в другие функциональные модули, продолжайте, это не повредит. Просто запомните эмпирическое правило о поставщиках приложений в forRoot, и вы должны быть хорошими. –