Angular2 Http覆盖注入路由器



在我们使用旧组件路由器的Angular2 RC4应用程序中,我们重写了默认的Http类来捕获Http 401未经身份验证的请求,并将它们重定向到登录页面。这个重定向发生在Angular路由器上。

我们现在想升级到2.0.1版本并使用新的路由器。要做到这一点,我们还必须将新的路由器注入到自定义Http覆盖类中。编译成功了,但Angular不会运行,因为当应用启动时,它会尝试在加载第一个组件之前创建自定义http类。在加载第一个组件之前,不可能再注入新的路由器。

在这里进行的最好方法是什么?我们应该在实例化Http覆盖类之后手动注入Router吗?怎么才能做到呢?

下面是我们在RC4中使用旧路由器的自定义Http类的代码。当更新到最终版本时,问题出现在catchUnauthorized,因为路由器不能再被注入到该类中。

import {Injectable} from "@angular/core";
import {Http, Headers, ConnectionBackend, RequestOptions, RequestOptionsArgs, Response, Request} from '@angular/http';
import {Observable} from 'rxjs/Observable';
import {Router} from '@angular/router-deprecated';
@Injectable()
export class CustomHttp extends Http {
constructor(backend: ConnectionBackend, defaultOptions: RequestOptions, private router: Router) {
    super(backend, defaultOptions);
}
postJson(url: string, object: any, options: RequestOptionsArgs = {}): Observable<Response> {
    var body = JSON.stringify(object);
    if(!options.headers)
    {
        options.headers = new Headers();
    }
    options.headers.set("Content-Type", "application/json");
    return this.post(url, body, options);
}
request(url: string | Request, options?: RequestOptionsArgs): Observable<Response> {
    return super.request(url, options)
        .catch(this.catchUnauthorized);
}
get(url: string, options?: RequestOptionsArgs): Observable<Response> {
    return super.get(url, options)
        .catch(this.catchUnauthorized);
}
post(url: string, body: string, options?: RequestOptionsArgs): Observable<Response> {
    return super.post(url, body, options)
        .catch(this.catchUnauthorized);
}
put(url: string, body: string, options?: RequestOptionsArgs): Observable<Response> {
    return super.put(url, body, options)
        .catch(this.catchUnauthorized);
}
delete(url: string, options?: RequestOptionsArgs): Observable<Response> {
    return super.delete(url, options)
        .catch(this.catchUnauthorized);
}
patch(url: string, body: string, options?: RequestOptionsArgs): Observable<Response> {
    return super.patch(url, body, options)
        .catch(this.catchUnauthorized);
}
head(url: string, options?: RequestOptionsArgs): Observable<Response> {
    return super.head(url, options)
        .catch(this.catchUnauthorized);
}
public catchUnauthorized = (error: Response) => {
    if (error.status === 401 || error.status === 440) {
        var currentInstruction = this.router.currentInstruction;
        var instruction = this.router.generate(["/Login", { "session": "true", "returnUrl": currentInstruction.toLinkUrl() }]);
        if (currentInstruction.urlPath != instruction.urlPath)
            this.router.navigateByInstruction(instruction);
        return Observable.throw('Sessie verlopen!');
    }
    if (error.status === 403) {
        this.router.navigate(['/Error', { 'error': 'forbidden' }]);
        return Observable.throw('Forbidden!');
    }
    return Observable.throw(error);
};
}

我也遇到了同样的问题。尝试将"Router"添加到"deps":

...
providers: [
{
  provide: CustomHttp,
  useFactory: (backend: XHRBackend, options: RequestOptions, route: Router) => {
    return new CustomHttp(backend, options, route);
  },
  deps: [ XHRBackend, RequestOptions, Router ]
}
...

如果你想使用自定义类,但到处都有来自'@angular/http'的导入,提供商必须提供来自'@angular/http'的http类,

import {Http} from '@angular/http';
import {CustomHttp} from 'my/custom/location';
function httpFactory(backend, options){
   return new CustomHttp(backend, options);
}
{
   provide: Http,
   useFactory: httpFactory,
   deps: [XHRBackend, RequestOptions]
}

你甚至可以把httpFactory方法放在同一个文件中,作为CustomHttp类

最新更新