Angular HTTP Interceptor-在多模块应用中显示微调器 [英] Angular HTTP Interceptor - Display spinner in multi-module app

查看:114
本文介绍了Angular HTTP Interceptor-在多模块应用中显示微调器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试显示ng4-loading-spinner微调器,用于对我的API进行的HTTP调用.

I'm trying to display the ng4-loading-spinner spinner for HTTP calls made to my API.

我的代码基于以下链接中的示例:

I based my code on the examples in the following links:

  • https://angular.io/guide/http#intercepting-all-requests-or-responses
  • Angular4: Using HttpClient's interceptor to setup a spinner

我的Angular 5应用包含多个模块. HTTP拦截器在服务"模块中.

My Angular 5 app has multiple multiple modules. The HTTP interceptor is in the "services" module.

我认为我遇到了依赖项注入问题,因为当我使用Chrome Dev Tools调试代码时,代码HTTP拦截器代码未执行.

I think I'm having a dependency injection problem because the code HTTP interceptor code doesn't get executed when I debug my code with Chrome Dev Tools.

api-interceptor.ts

import 'rxjs/add/operator/do';
import 'rxjs/add/operator/catch'
import { Observable } from 'rxjs/Observable';
import { Injectable } from '@angular/core';
import {
    HttpEvent,
    HttpInterceptor,
    HttpHandler,
    HttpRequest,
    HttpResponse
} from '@angular/common/http';
import { Ng4LoadingSpinnerService } from 'ng4-loading-spinner';

@Injectable()
export class ApiInterceptor implements HttpInterceptor {

    private count: number = 0;

    constructor(private spinner: Ng4LoadingSpinnerService) { }

    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        this.count++;

        if (this.count == 1) this.spinner.show();

        let handleObs: Observable<HttpEvent<any>> = next.handle(req);

        handleObs
            .catch((err: any) => {
                this.count--;
                return Observable.throw(err);
            })
            .do(event => {
                if (event instanceof HttpResponse) {
                    this.count--;
                    if (this.count == 0) this.spinner.hide();
                }
            });

        return handleObs;
    }

}

api.service.ts

import { Injectable, Inject } from '@angular/core';
import { Http, Response, Headers, RequestOptions } from '@angular/http';
import { Observable } from 'rxjs/Observable';

import { TokenService } from './token.service';

@Injectable()
export class ApiService {

    constructor(
        private http: Http,
        private session: TokenService,
        @Inject('BASE_URL') private baseUrl) { }

    get(entityRoute: string): Observable<Response> {
        let apiRoute = this.getApiRoute(entityRoute);
        let options = this.generateRequestOptions();

        return this.http.get(apiRoute, options);
    }

    post<T>(entityRoute: string, entity: T): Observable<Response> {
        let apiRoute = this.getApiRoute(entityRoute);
        let options = this.generateRequestOptions();

        return this.http.post(apiRoute, entity, options);
    }

    put<T>(entityRoute: string, entity: T): Observable<Response> {
        let apiRoute = this.getApiRoute(entityRoute);
        let options = this.generateRequestOptions();

        return this.http.post(apiRoute, entity, options);
    }

    private getApiRoute(entityRoute: string): string {
        return `${this.baseUrl}api/${entityRoute}`;
    }

    private generateRequestOptions(): RequestOptions {
        let headersObj = null;
        let accessToken = this.session.getAccessToken();

        if (accessToken) {
            headersObj = {
                'Content-Type': 'application/json',
                'Authorization': 'Bearer ' + accessToken
            };
        } else {
            headersObj = {
                'Content-Type': 'application/json'
            };
        }

        let headers = new Headers(headersObj);
        return new RequestOptions({ headers: headers });
    }

}

services.module.ts

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { HttpModule } from '@angular/http';
import { Ng4LoadingSpinnerModule } from 'ng4-loading-spinner';

import {
    ApiInterceptor,
    ApiService,
    TokenService
} from './index';

@NgModule({
    imports: [
        CommonModule,
        HttpModule,
        Ng4LoadingSpinnerModule
    ],
    providers: [
        ApiInterceptor,
        ApiService,
        TokenService
    ]
})
export class ServicesModule { }

export * from './index';

app.module.ts

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { Ng4LoadingSpinnerModule } from 'ng4-loading-spinner';

import { BootstrapModule } from './bootstrap/bootstrap.module';
import { ServicesModule, ApiInterceptor } from './services/services.module';
import { AppComponent } from './app-component';

@NgModule({
    bootstrap: [ AppComponent ],
    imports: [
        BrowserModule,
        Ng4LoadingSpinnerModule.forRoot(),
        BootstrapModule,
        ServicesModule
    ],
    providers: [
        {
            provide: 'BASE_URL',
            useFactory: getBaseUrl
        },
        {
            provide: HTTP_INTERCEPTORS,
            useClass: ApiInterceptor,
            multi: true,
        }
    ]
})
export class AppModule {
}

export function getBaseUrl(): string {
    return document.getElementsByTagName('base')[0].href;
}

推荐答案

问题是ApiService使用的是@angular/http中的Http而不是@angular/common/http中的HttpClient.

The issue was the ApiService was using the Http from @angular/http instead of HttpClient from @angular/common/http.

所以ApiInterceptor没有什么可拦截的.

So the ApiInterceptor has nothing to intercept.

这篇关于Angular HTTP Interceptor-在多模块应用中显示微调器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆