我目前正在尝试为angular2应用创建自定义XHRBackend
。我想用401 http响应代码(未授权)捕获所有http响应,以在登录页面上重定向用户。但是我的问题出现了: DI无法在我的自定义后端加载Router
。
@Injectable()
export class CustomXHRBackend extends XHRBackend {
constructor(
_browserXHR: BrowserXhr,
_baseResponseOptions: ResponseOptions,
_xsrfStrategy: XSRFStrategy,
private router : Router) {
super(_browserXHR, _baseResponseOptions, _xsrfStrategy);
console.log(router); // --> undefined
}
createConnection(request: Request) {
let xhrConnection = super.createConnection(request);
xhrConnection.response = xhrConnection.response.catch((error, caugth) => {
if(error.status === 401) {
//Do stuff with the new router
this.router.navigate(['/login']);
}
return Observable.throw(caugth);
});
return xhrConnection;
}
}
似乎DI仍然使用XHRBackend
的元数据,因为前3个参数被定义。
我创建了一个plunkr,它演示了这个问题:http://plnkr.co/edit/44imf9KpE06cIyQ395sg?p=preview
注意:
plunkr基于angular2路由器示例,遗憾的是我没有足够的时间来创建一个较小的。
重要文件为custom.backend.ts
,可能为main.ts
。
有人知道,为什么会这样?
答案 0 :(得分:2)
为此,我会扩展Http
类。这是一个示例:
@Injectable()
export class CustomHttp extends Http {
constructor(backend: ConnectionBackend, defaultOptions: RequestOptions) {
super(backend, defaultOptions);
}
request(url: string | Request, options?: RequestOptionsArgs): Observable<Response> {
console.log('request...');
return super.request(url, options).catch(res => {
// do something
});
}
get(url: string, options?: RequestOptionsArgs): Observable<Response> {
console.log('get...');
return super.get(url, options).catch(res => {
// do something
});
}
}
并按如下所述进行注册:
bootstrap(AppComponent, [HTTP_PROVIDERS,
new Provider(Http, {
useFactory: (backend: XHRBackend, defaultOptions: RequestOptions) => new CustomHttp(backend, defaultOptions),
deps: [XHRBackend, RequestOptions]
})
]);
修改强>
我认为您需要使用useFactory
明确提供参数:
import {provide} from '@angular/core';
import {Router} from '@angular/router';
import { bootstrap } from '@angular/platform-browser-dynamic';
import { AppComponent } from './app.component';
import { APP_ROUTER_PROVIDERS } from './app.routes';
import {HTTP_PROVIDERS, Http,RequestOptions, XHRBackend, XSRFStrategy, BrowserXhr} from '@angular/http';
import {CustomXHRBackend} from './custom.backend';
bootstrap(AppComponent, [
APP_ROUTER_PROVIDERS,
HTTP_PROVIDERS,
provide(XHRBackend, {
useFactory: (browserXHR: BrowserXhr, requestOptions: RequestOptions, xsrfStrategy: XSRFStrategy, router: Router) => {
return new CustomXHRBackend(browserXHR, requestOptions, xsrfStrategy, router);
},
deps: [BrowserXhr, RequestOptions, XSRFStrategy, Router]
})
]);
请参阅此plunkr:http://plnkr.co/edit/JK3q5nspZ434AeJJsUeJ?p=preview。