【问题标题】:How to create HttpInterceptors across modules?如何跨模块创建 HttpInterceptor?
【发布时间】:2020-02-22 06:38:01
【问题描述】:

我对 HttpInterceptors Angular 文档底部的 usage note 很好奇,它指出:

要对整个应用程序使用相同的 HttpInterceptors 实例, 仅在您的 AppModule 中导入 HttpClientModule,然后添加 根应用程序注入器的拦截器。如果你导入 HttpClientModule 跨不同模块多次(例如, 在延迟加载模块中),每次导入都会创建一个新的副本 HttpClientModule,它覆盖了提供的拦截器 根模块。

我不明白该怎么做。如何获取根应用程序注入器并将我的延迟加载模块的 HttpInterceptor 添加到其中?

似乎How to import Angular HTTP interceptor only for Child module 也在尝试回答这个问题,但我同样不清楚。

为什么这不起作用,以及如何正确添加第二个延迟加载的拦截器?

应用模块

@NgModule({
  imports: [RouterModule.forRoot(routes)], // routes contains a lazy load module
  declarations: [AppComponent],
  bootstrap: [AppComponent],
  providers: [
    {
      provide: HTTP_INTERCEPTORS,
      useClass: TokenInterceptorService,
      multi: true,
    }
  ]
})
export class AppModule { }

延迟加载子模块

@NgModule({
  imports: [
    LazyRoutingModule
  ],
  declarations: [ChildComponent],
  providers: [
    {
      provide: HTTP_INTERCEPTORS,
      useClass: CacheInterceptorService,
      multi: true,
    }
  ]
})
export class LazyModule { }

【问题讨论】:

  • 为什么投反对票?我研究了这个主题,尽我最大的努力寻找可行的解决方案,并提出了一个具体而明确的问题。
  • 您最初的问题是:“这样的东西会起作用吗?”。这表明缺乏研究,因为回答问题的简单方法是测试它。我已经撤回了我的反对票,因为你显然最终测试了它。也就是说,答案就在问题中:将拦截器添加到根应用程序注入器
  • 我知道你会如何得出结论,我的问题可能过于意识流。但这正是我不理解的单词序列。您的意思是唯一的解决方案是在 AppModule 中提供所有拦截器吗?这不是急切加载拦截器及其所有依赖项,可能急切加载整个延迟加载的模块吗?
  • 好吧,你会尽量减少依赖。也就是说,AFAIK,您还可以在延迟加载的模块中重新导入 HttpClientModule:请注意,它不会为根模块中定义的 HttpClient 定义拦截器。
  • @RobinDeSchepper 您找到解决方案了吗?你能给我举个例子吗?

标签: angular angular-httpclient angular-http-interceptors


【解决方案1】:

早上好,

请原谅我的英语,但我正在用谷歌翻译器翻译。

我正在开发一个带有几个惰性模块的应用程序,我刚刚开发了一个HttpInterceptor,我没有遇到任何问题,我所做的过程如下:

HttpInterceptor

import { Injectable } from '@angular/core';
import {
    HttpInterceptor,
    HttpRequest,
    HttpHandler,
    HttpEvent,
    HttpErrorResponse
} from '@angular/common/http';

import { Observable, throwError } from 'rxjs';
import { catchError, retry } from 'rxjs/operators';
import { NotifierService } from 'angular-notifier';

@Injectable()
export class HttpErrorInterceptor implements HttpInterceptor {

    constructor(private notifier: NotifierService) { }

    intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        return next.handle(request).pipe(
            retry(1),
            catchError((error: HttpErrorResponse) => {
                this.notifier.notify('error', error && error.message ? error.message : 'Error');
                return throwError(error);
            }
            ));
    }
}

并且要简单地导入 app.module 的提供者 添加:

{
       provide: HTTP_INTERCEPTORS,
       useClass: HttpErrorInterceptor,
       multi: true
}

我认为您遇到的问题是,当您还在子项中实例化时,您会创建一个新实例,这会产生问题。在做之前我已经阅读了几篇文章,表明它不应该工作,但它确实哈哈。

以防万一它来自某个新版本的 Angular,我将我正在处理的项目的数据放入:

Angular CLI:8.3.25 节点:13.3.0 角度:8.2.14

【讨论】:

    猜你喜欢
    • 2019-07-16
    • 1970-01-01
    • 2013-03-14
    • 2013-09-25
    • 1970-01-01
    • 1970-01-01
    • 2021-12-30
    • 2016-06-23
    • 2010-10-07
    相关资源
    最近更新 更多