4

我正在尝试将我的项目从angular 4升级到angular 5。
为此,我需要将Http的使用升级到HttpClient

但是,我的 HttpService 是使用其他服务包装的,并且在设置 environment == "develop" 时与 MockConnectionBackend 一起使用,我无法弄清楚更改类结构以使用 HttpClient 的正确方法是什么。

export enum HttpRequestType {
  Secured = 1,
  Regular = 2
}

@Injectable()
//I use the HttpFactoryService in order to enable the caller to force a secure connection (call will be submitted only if user is logged in)
export class HttpFactoryService {

  constructor(private readonly http: Http,
    private readonly secureHttp: SecureHttpService,
    private readonly oauth2: OAuth2Service) { }
  
  public get(httpRequestType?: HttpRequestType): HttpApi {
    let useSecureConnection = httpRequestType == HttpRequestType.Secured || this.oauth2.isAuthenticated();
    if (useSecureConnection) {
      return this.secureHttp;
    }
    return this.http;
  }
}


//Secure http check if user is logged in. if not request is aborted.
//If user is logged in than we add the authorized header
@Injectable()
export class SecureHttpService implements HttpApi {

  constructor(private readonly http: Http,
    private readonly oauth2: OAuth2Service,
    private readonly router: Router) {
  }

  get(url: string, options?: RequestOptionsArgs): Observable<Response> {
    return this.request(url, extend({}, options, { method: RequestMethod.Get }));
  }

  post(url: string, body: any, options?: RequestOptionsArgs): Observable<Response> {
    return this.request(url, extend({}, options, {
      body: body,
      method: RequestMethod.Post
    }));
  }

  put(url: string, body: any, options?: RequestOptionsArgs): Observable<Response> {
    return this.request(url, extend({}, options, {
      body: body,
      method: RequestMethod.Put
    }));
  }

  delete(url: string, options?: RequestOptionsArgs): Observable<Response> {
    return this.request(url, extend({}, options, { method: RequestMethod.Delete }));
  }

  patch(url: string, body: any, options?: RequestOptionsArgs): Observable<Response> {
    return this.request(url, extend({}, options, {
      body: body,
      method: RequestMethod.Patch
    }));
  }

  head(url: string, options?: RequestOptionsArgs): Observable<Response> {
    return this.request(url, extend({}, options, { method: RequestMethod.Head }));
  }

  options(url: string, options?: RequestOptionsArgs): Observable<Response> {
    return this.request(url, extend({}, options, { method: RequestMethod.Options }));
  }

  request(request: string|Request, options?: RequestOptionsArgs): Observable<Response> {
    return this.oauth2.getAccessToken()
      .flatMap((accessToken: string) => {
        options = options || {};
        options.headers = options.headers || new Headers();
        options.headers.append("Authorization", accessToken);

        return this.http.request(request, options);
      })
      .catch((err:any) => {
        if (err.status == HttpStatusCodes.Unauthorized) {
          this.router.navigate(['/login']);
        }
        return Observable.throw(err);
      })
  }

}


//I created my own Http service 
@NgModule({
  imports: [//Cleard for simplicity]
  exports: [//Cleard for simplicity],
  declarations: [//Cleard for simplicity]
  providers: [
    HttpCacheService,
    //Mocks
    MockBackend,
    MockBackendConnector,
    {
      provide:Http,
      deps: [
           XHRBackend,
           MockBackend,
           HttpCacheService,
           MockBackendConnector,
      ],
      useFactory: createHttpService
    }
  ]
})



export function createHttpService(xhrBackend: XHRBackend,
                                  mockBackend: MockBackend,
                                  httpCacheService: HttpCacheService,
                                  mockBackendConnector: MockBackendConnector) {
  let xhrHttpService = new HttpService(xhrBackend, httpCacheService)
  if (environment.production) {
    return xhrHttpService; //On production always cancel mock
  }
  
  //We use the xhrHttpService inside mockBackendConnector in order to create a xhr call when the mock route is not presented in the mock routes
  mockBackendConnector.connect(mockBackend, null, xhrHttpService);                                  
  return new HttpService(mockBackend, httpCacheService);
}



//My http service , extends the default http service calls
@Injectable()
export class HttpService extends Http implements HttpApi{

  constructor(backend: ConnectionBackend,
              private httpCacheService: HttpCacheService) {
    super(backend, new BaseRequestOptions());
  }

  get(url: string, options?: RequestOptionsArgs): Observable<Response> {
    return this.request(url, extend({}, options, { method: RequestMethod.Get }));
  }

  post(url: string, body: any, options?: RequestOptionsArgs): Observable<Response> {
    return this.request(url, extend({}, options, {
      body: body,
      method: RequestMethod.Post
    }));
  }

  put(url: string, body: any, options?: RequestOptionsArgs): Observable<Response> {
    return this.request(url, extend({}, options, {
      body: body,
      method: RequestMethod.Put
    }));
  }

  delete(url: string, options?: RequestOptionsArgs): Observable<Response> {
    return this.request(url, extend({}, options, { method: RequestMethod.Delete }));
  }

  patch(url: string, body: any, options?: RequestOptionsArgs): Observable<Response> {
    return this.request(url, extend({}, options, {
      body: body,
      method: RequestMethod.Patch
    }));
  }

  head(url: string, options?: RequestOptionsArgs): Observable<Response> {
    return this.request(url, extend({}, options, { method: RequestMethod.Head }));
  }

  options(url: string, options?: RequestOptionsArgs): Observable<Response> {
    return this.request(url, extend({}, options, { method: RequestMethod.Options }));
  }

  request(request: string|Request, options?: RequestOptionsArgs): Observable<Response> {
    options = options || {};
    let url: string;

    if (typeof request === 'string') {
      url = request;
      request = this.isAbsoluteUrl(url) ? url: environment.serverUrl + url;
    } else {
      url = request.url;
      request.url = this.isAbsoluteUrl(url) ? url: environment.serverUrl + url;
    }

    if (!options.cache) {
      return this.httpRequest(request, options);
    }
    
    return this.tryFromCacheAndCacheResult(request, url, options);
  }
  
  private tryFromCacheAndCacheResult(request: string|Request, url: string, options?: RequestOptionsArgs):Observable<Response> {
 
  }
  // Customize the default behavior for all http requests here if needed
  private httpRequest(request: string|Request, options: RequestOptionsArgs): Observable<Response> {
      let req = super.request(request, options);
      if (!options.skipErrorHandler) {
        req = req.catch(this.errorHandler.bind(this));
      }
      return req;
  }

  // Customize the default error handler here if needed
  private errorHandler(response: Response): Observable<Response> {
    if (environment.production) {
      // Avoid unchaught exceptions on production
      log.error('Request error', response);
      return Observable.throw(response);
    }
    throw response;
  }

  private isAbsoluteUrl(url:string): boolean {
    return /^https?:\/\//i.test(url);
  }
}

我觉得我做的太复杂了。我的问题是我不能对 HttpClient 使用相同的方法,并且无法理解如何按照建议使用拦截器。

4

0 回答 0