angular - Angular向子模块注入不同的服务实现
问题描述
我有一个实现 ErrorHandler 的类,并在根级别提供。我的应用程序中有 3 个模块,其中 2 个可以在根级别使用 ErrorHandler,但其中一个应该有不同版本的 ErrorHandler。
我已经尝试创建 ErrorHandler 的两个实现,其中一个在根级别提供,我用 {providedIn: ThreePageModule} 装饰了第二个服务,但这似乎不像每当出现错误时那样工作:HttpErrorResponse 根级别ErrorHandler 开始了。我查看了角度文档,它说当子模块延迟加载时,它会获得提供的服务。我在这里错过了什么吗?
下面是 app.module.ts
@NgModule({
declarations: [AppComponent],
entryComponents: [],
imports: [
FormsModule,
BrowserModule,
HttpClientModule,
AppRoutingModule
],
providers: [
....other services...
{
provide: HTTP_INTERCEPTORS,
useClass: HttpConfigInterceptor,
multi: true
},
{ provide: ErrorHandler, useClass: ExceptionHandlerService },
],
bootstrap: [AppComponent]
})
export class AppModule {}
AppRoutingModule.ts:
@NgModule({
imports: [
RouterModule.forRoot(appRoutes)
],
exports: [
RouterModule
]
})
export class AppRoutingModule { }
appRoutes.ts:
export const appRoutes: Routes = [
{
path: 'one',
loadChildren: './../one/one.module#OnePageModule'
},
{
path: 'two',
loadChildren: './../two/two.module#TwosPageModule'
},
{
path: 'three',
loadChildren: './../three/three.module#ThreePageModule'
}
];
三模块.ts
@NgModule({
imports: [
...Imports...
],
entryComponents: [
ThreeComponent
],
providers: [DatePipe],
declarations: [
....Declarations.....
]
})
export class ClaimsPageModule { }
ThreeErrorHandlerService.ts
@Injectable({
providedIn: ThreePageModule
})
export class ThreeErrorHandlerService implements ErrorHandler {
constructor() { }
handleError(error: Error | HttpErrorResponse): void {
if (error instanceof HttpErrorResponse) {
return;
}
}
}
我想要的是在 ThreePageModule 中使用 ThreeErrorHandlerService,同时在其余两个模块中仍然使用 ExceptionHandlerService。
这是我们实现它的方式还是我做错了。
解决方案
我认为有一种方法可以实现这一目标。
app.tokens.ts
export function errorHandlerFactory (r: Router): AbstractErrorHandler {
return r.url === '/foo' ? new ErrorHandlerThree('foo error!') : new ErrorHandlerOne('not foo !!')
}
export abstract class AbstractErrorHandler {
abstract getCrtErr: () => string;
}
export class ErrorHandlerOne implements AbstractErrorHandler {
constructor (public crtErr: string) { }
getCrtErr () { return 'err!' }
}
export class ErrorHandlerThree implements AbstractErrorHandler {
constructor (public crtErr: string) { }
getCrtErr () { return 'err!' }
}
app.module.ts
@Component({
selector: 'my-app',
template: `
<button [routerLink]="'foo'">foo route</button>
<router-outlet></router-outlet>
`,
})
class AppComponent {
constructor (err: AbstractErrorHandler) {
console.log(err) // not foo !!
}
}
const routes: Routes = [
{ path: 'foo', loadChildren: () => import('./foo/foo.module').then(m => m.FooModule,) },
]
@NgModule({
imports: [
BrowserModule,
RouterModule.forRoot(routes),
],
declarations: [
AppComponent
],
providers: [
{ provide: AbstractErrorHandler, useFactory: errorHandlerFactory, deps: [Router] }
],
bootstrap: [AppComponent]
})
export class AppModule { }
foo.module.ts
@Component({
selector: 'foo-comp',
template: `this is foo!`,
})
export class FooComp {
constructor (err: AbstractErrorHandler) {
console.log('foo', err) // foo error!
}
}
const routes: Routes = [
{ path: '', component: FooComp, }
]
@NgModule({
declarations: [FooComp],
imports: [
CommonModule,
RouterModule.forChild(routes),
],
providers: [
{ provide: AbstractErrorHandler, useFactory: errorHandlerFactory, deps: [Router] }
],
请注意,您可能需要在内部跟踪类实例,app.tokens.ts
因为您可能不希望每次组件注入您的 this 依赖项时都需要一个新实例。
推荐阅读
- ios - 登录后无法在仅显示根 ViewController 的不同 View Controller 之间导航
- c# - WPF列表框不添加整个字符串
- postgresql - 让数据库身份验证在 Apache Guacamole 上工作
- java - Java PriorityQueue NPE 即使添加的元素不为空?
- sql-server - 数据库列数据类型从位更改为 char(1) SQL
- c++ - c ++ int指向数组指针数组的指针内存泄漏
- java - 空指针异常:com.google.android.gms.auth.api.GoogleSigninAccount(getIdtoken)
- r - R:按年份对离散时间序列进行分组
- python - 将不可打印的字节转换为字符串
- javascript - 如何使用 Angular 为 js-calender-year 中的每个选定日期添加颜色。页面刷新后颜色应保持不变