在组件中注入http拦截器

时间:2017-11-14 21:00:16

标签: angular angular-http-interceptors

我创建了这个http拦截器:

@Injectable()
export class NoopInterceptor  implements HttpInterceptor {
    public my_status: boolean = true;
    private _statusChange: Subject<boolean> = new Subject<boolean>();
    public statusChange$ = this._statusChange.asObservable();
    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        this.changeStatus(false);
        const my_req = req.clone({
            url: API_PATH + req.url
        });
        return next
            .handle(my_req)
            .do(event => {
                if (event instanceof HttpResponse)
                    this.changeStatus(true);
            });
    }

    private changeStatus(status: boolean) {
        this.my_status = status;
        this._statusChange.next(this.my_status);
    }
}

在我的组件中,我做到了:

export class AppComponent implements OnInit {
    public my_status: boolean;
    constructor(private httpInterceptor: NoopInterceptor) {
        this.my_status = httpInterceptor.my_status;
        httpInterceptor.statusChange$.subscribe(this.changeStatus);
    }

    changeStatus(status: boolean) {
        this.my_status = status;
    }

}

app.module,我提供了这样的拦截器:

providers: [
   {
        provide: HTTP_INTERCEPTORS,
        useClass: NoopInterceptor,
        multi: true
    }
]

当我按照上面的方式进行操作时,我得到No provider for NoopInterceptor!,因为我没有提供NoopInterceptor,但如果我提供NoopInterceptor这样的话:

providers: [
   {
        provide: HTTP_INTERCEPTORS,
        useClass: NoopInterceptor,
        multi: true
    },
    NoopInterceptor
]

我会接受两次注射,组件会出错,然后我就无法订阅statusChange。我该如何解决这个问题?

2 个答案:

答案 0 :(得分:4)

可能用以下方法创建单个拦截器实例:

providers: [
    NoopInterceptor,
   {
        provide: HTTP_INTERCEPTORS,
        useExisting: NoopInterceptor,
        multi: true
    }
]

但是加载指示符状态的正确解决方案(我猜statusChange用于此目的)是将它从拦截器中分离出来并使其成为一个单独的提供者。

正如它显示的here,应该有请求计数器,因为可以同时发出请求,并且它应该受到成功和错误do回调的影响。

答案 1 :(得分:3)

您是否尝试在提供HTTP_INTERCEPTOR之前放置NoopInterceptor并使用Excel而不是useClass? 以这种方式,你应该只获得一个NoopInterceptor实例。