Angular внедрение другой реализации сервиса в дочерний модуль - PullRequest
0 голосов
/ 16 января 2020

У меня есть класс, реализующий ErrorHandler, и он предоставляется на уровне root. У меня есть 3 модуля в моем приложении, из которых 2 из них могут использовать ErrorHandler на уровне root, но один из них должен иметь другую версию ErrorHandler.

Я попытался создать две реализации ErrorHandler, одна из которых предоставленный на уровне root, я украсил вторую службу с помощью {обеспечитьIn: ThreePageModule}, но это не похоже на работу, так как всякий раз, когда возникает ошибка, например: HttpErrorResponse запускается ErrorHandler уровня root. Я смотрел на angular документация, в которой говорится, что, когда дочерний модуль загружается лениво, он получает предоставленную услугу. Я что-то здесь упускаю ??

Ниже приведен файл 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'
  }
 ];

ThreeModule.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;
  }
 }
}

Я хочу использовать ThreeErrorHandlerService в ThreePageModule, все еще используя ExceptionHandlerService в остальных двух модулях.

Так мы добиваемся этого или я ошибаюсь.

1 Ответ

0 голосов
/ 17 января 2020

Я думаю, что есть способ достичь этого.

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, поскольку вам может не потребоваться новый экземпляр каждый раз, когда компонент вводит эту зависимость.

FactoryProvider .

Демонстрационная версия .

...