2016-12-07 5 views
3

Недавно я разделил свой одиночный AppModule на несколько модулей, и теперь я пытаюсь лениво загрузить модуль и использовать его для использования однопользовательских сервисов из общего модуля.Службы Singleton недоступны для ленивых загружаемых модулей

Я выполнил указанные шаги in the docs (а также in this tutorial) и создал общий CoreModule, который предоставляет услуги Singleton. Однако, когда один из сервисов общего доступа модуля пытается внедрить какие-либо из одноэлементных услуг следующее исключение:

EXCEPTION: Uncaught (in promise): Error: No provider for HttpClientService! 
Error: No provider for HttpClientService! 
    at NoProviderError.BaseError [as constructor] (http://localhost:5000/lib/angular/@angular/core/bundles/core.umd.js:1105:38) 

app.module.ts

@NgModule({ 
    imports: [ 
     BrowserModule, 
     CoreModule.forRoot(), 
     AppRoutingModule 
    ] 
}) 
export class AppModule { } 

app-routing.module.ts

export const routes: Routes = [ 
    { 
     path: "mailgroups", 
     loadChildren: "app/mailgroup/mailgroup.module#MailGroupModule" // <-- lazy loading the module 
    } 
]; 

@NgModule({ 
    imports: [ RouterModule.forRoot(routes) ], 
    exports: [ RouterModule ], 
}) 
export class AppRoutingModule { } 

core.module.ts (общий модуль)

export class CoreModule { 
    constructor (@Optional() @SkipSelf() parentModule: CoreModule) { 
     if (parentModule) { 
      throw new Error("CoreModule is already loaded. Import it in the AppModule only!"); 
     } 
    } 

    static forRoot(): ModuleWithProviders { 
     return { 
      ngModule: CoreModule, 
      providers: [ 
       HttpClientService, // <-- singleton service 1 
       UserService   // <-- singleton service 2 
      ] 
     }; 
    } 
} 

mailgroup.module.ts (ленивый модуль загружен)

@NgModule({ 
    imports: [ 
     MailGroupRoutingModule 
    ] 
}) 
export class MailGroupModule { } 

Что интересно, что когда я импортировать общий модуль CoreModule к ленивому загруженному модулю MailGroupModule, я не Не получаю никакого исключения (несмотря на throw new Error(...) в конструкторе), потому что аргумент parentModule всегда null.

Я пропустил что-то очевидное здесь? (опущенные заявления, которые я счел ненужными)

ответ

2

После многих часов программирования «наугад», вытягивая мои волосы, мои усилия окупились. Вопрос был в плохой конфигурации system.config.js.

При сравнении SystemJS-конфигурации с the systemjs.config.web.js used in the docs я заметил тонкие различия в том, как папка приложения и путь к файлу, который загружает приложение, настроены в моем файле.

✘ Перед (Malconfigured SystemJS)

System.config({ 
    paths: { ... }, 
    map: { 
     app: '/app',    // <-- This line (incorrect) 
     ... 
    }, 
    packages: { 
     app: { 
      main: '/main.js'  // <-- And this line (incorrect) 
      defaultExtension: 'js' 
     } 
    } 
}) 

Обратите внимание на слэш в app: '/app' и относительный путь в main: '/main.js'.

✔ После (конфигурация Correct SystemJS)
(изменено на app: 'app' и main: './main.js')

System.config({ 
    paths: { ... }, 
    map: { 
     app: 'app',     // <-- This line (correct) 
     ... 
    }, 
    packages: { 
     app: { 
      main: './main.js'  // <-- And this line (correct) 
      defaultExtension: 'js' 
     } 
    } 
}) 

Таким образом, эти две тонкие исправления сделаны все различия в мире!

Теперь, пытаясь импортировать совместно используемый модуль CoreModule в любом месте, кроме AppModule, в результате возникает исключение, как и ожидалось.

1

Согласно лучшей практике, CoreModule является расширением для AppModule. он не должен быть общим модулем. его следует импортировать и использовать только AppModule совместно используемым модулем. SharedModule