我最近将单个AppModule
拆分为多个模块,现在我正在尝试延迟加载模块并使其使用来自共享模块的单例服务。
我按照提及的步骤in the docs(以及in this tutorial)创建了一个提供单例服务的共享CoreModule
。但是,当其中一个共享模块的服务尝试注入任何单例服务时,会抛出以下异常:
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
。
我错过了一些明显的东西吗? (遗漏了我认为不必要的声明)
答案 0 :(得分:2)
经过几个小时的编程&#34;随意&#34;在拔头发的同时,我的努力得到了回报。该问题出现在配置错误的 system.config.js
中。
将SystemJS配置与the systemjs.config.web.js
used in the docs进行比较时,我注意到在我的文件中配置app文件夹和引导应用程序的文件路径的方式存在细微差别。
✘之前(错误配置的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'
中的相对路径。
✔之后(正确的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 :(得分:1)
根据最佳实践,CoreModule是AppModule的扩展。它不应该是一个共享模块。它只能由AppModule导入和使用 一个共享模块,应该被称为..... SharedModule