我正在使用Angular 2 RC2。我需要将Angular 2路由器注入我的自定义ExceptionHandler类。但是我收到以下错误
错误:错误:无法解析' ErrorHandler'(?)的所有参数。 确保所有参数都使用Inject或者装饰 有效的类型注释和那个' ErrorHandler'装饰着 可注射的。
我确实试过装饰私有路由器:使用@Inject的路由器无济于事。我使用打字稿,因此我认为我不需要@Inject属性。
我的自定义ExceptionHandler看起来像这样
import { ExceptionHandler } from '@angular/core';
import { Router } from '@angular/router';
export class ErrorHandler extends ExceptionHandler{
constructor(
private router: Router
){
super(null, null);
}
call(error, stackTrace = null, reason = null) {
console.log(error);
this.router.navigate(['/error']);
}
}
我的main.ts看起来像这样
import { bootstrap } from '@angular/platform-browser-dynamic';
import { AppComponent } from './app.component';
import { provide, ExceptionHandler } from '@angular/core';
import { ErrorHandler } from './error-handler/error-handler';
import { HTTP_PROVIDERS } from '@angular/http';
import { ROUTER_PROVIDERS } from '@angular/router';
bootstrap(AppComponent, [
HTTP_PROVIDERS,
ROUTER_PROVIDERS,
provide(ExceptionHandler, {useClass: ErrorHandler})
]);
为什么我收到此错误?在ExceptionHandler实例化时,路由器是否可注入?
完整的源代码可在此处获取
https://github.com/harindaka/angular2-seed-typescript/tree/b368315ce6608085f3154a03bc53f0404ce16495
答案 0 :(得分:4)
请参阅:ErrorHandler课程。您也可以添加Injectable
装饰器以实现DI!
import { ErrorHandler, Injectable } from '@angular/core';
@Injectable()
export class GlobalErrorHandler implements ErrorHandler {
private myService: MyService;
constructor(private injector: Injector) {
this.myService = injector.get(MyService);
}
handleError(error) {
alert('Bad things happening');
}
}
@NgModule({
providers: [
{
provide: ErrorHandler,
useClass: GlobalErrorHandler
}
]
})
export class AppModule { }

注意:以上答案使用ExceptionHandler
,在最终版本中删除了ErrorHandler
。
答案 1 :(得分:3)
更新 Presenter
已重命名为ExceptionHandler
https://stackoverflow.com/a/35239028/217408
<强> orgiginal 强>
我猜这是由循环依赖引起的。您可以通过注入注入器并强制获取路由器来解决此问题:
ErrorHandler
答案 2 :(得分:3)
可能迟到了派对,但这对我有用(Angular 2 RC4):
import { Injectable, Injector, ExceptionHandler } from '@angular/core';
import { Router } from '@angular/router';
@Injectable()
export class AppExceptionHandler extends ExceptionHandler {
private router;
injector: Injector;
constructor(injector: Injector) {
super(null, null);
this.injector = injector;
}
call(exception: any, stackTrace?: any, reason?: string): void {
if (this.router == null) {
this.router = this.injector.get(Router);
}
// do something with the error such as spitting out to console:
console.log('exception:', exception);
console.log('stackTrace:', stackTrace);
console.log('reason:', reason);
// navigate to custom error page (defined in your routes)
this.router.navigate(['error']);
}
}
然后在你的main.ts中:
bootstrap(AppComponent, [
HTTP_PROVIDERS,
APP_ROUTER_PROVIDERS,
provide(ExceptionHandler, { useClass: AppExceptionHandler })]
)
答案 3 :(得分:0)
这是一个非常简单的 - 要注入课程,你需要创建课程injectable
。听起来很熟悉吧?
如果您在@Injectable()
课程的顶部添加了ErrorHandler
,则应该有效。
import { ExceptionHandler, Injectable } from '@angular/core';
import { Router } from '@angular/router';
@Injectable()
export class ErrorHandler extends ExceptionHandler{
[...]
}
答案 4 :(得分:0)
刚出现类似的问题并像这样解决了(在app模块的providers数组中使用它):
{
provide: ExceptionHandler,
useFactory: (router) => {
return new ErrorHandler(router);
},
deps: [Router]
}
答案 5 :(得分:0)
所以今天我遇到了类似的事情。我的情况有点不同,我扩展了Http,需要Router。但是,ErrorHandler也需要Http。使用上面的方法与Factories,我想我可以将Http注入ErrorHandler。我发现当ErrorHandler在Http的构造函数中调用依赖注入时,Router不存在(也没有其他所有必需的上下文)。
所以我让注入器在函数调用期间给我一个实例,而不是在构造函数中。当注射器实际上试图获得Http(在调用中)时,它已经在适当的上下文中创建。
CustomErrorHandler.ts:
import { ErrorHandler, Injector } from '@angular/core';
import { Http } from '@angular/http';
import { environment } from 'environments/environment';
export class CustomErrorHandler extends ErrorHandler {
private http: Http;
constructor(private injector: Injector) {
super();
// Calling this.injector.get(Http); here resulted in a null Router
window.onerror = (msg: any, url: any, line: any, col: any, error: any) => {
this.handleError(msg);
return true;
};
}
public handleError(error: any): void {
try {
// calling the injector here gave the application the time to build the correct context for the dependency injection that Http needed.
if (!this.http) {
this.http = this.injector.get(Http);
}
if (!error) {
error = 'Unknown Error';
}
console.error(error);
this.http.post('logtoserver/LogError', { Message: error.message, StackTrace: error.stack });
} catch (exception) {
// ignore
}
}
}
CustomHttpService.ts中的相关部分:
@Injectable()
export class CustomHttpService extends Http {
constructor(backend: ConnectionBackend, defaultOptions: RequestOptions, private router: Router, private injector: Injector) {
super(backend, defaultOptions);
}
request(urlOrRequest: string | Request, options?: RequestOptionsArgs): Observable<Response> {
// We needed Router here to call this.router.navigate(['...']);
// ...
}
}
app.module.ts:
import { NgModule, ErrorHandler, Injector } from '@angular/core';
import { Http, RequestOptions, XHRBackend } from '@angular/http';
import { CustomErrorHandler } from 'app/customErrorHandler';
// ...
export function customHttpServiceFactory(xhrBackend, requestOptions, router, injector) {
return new CustomHttpService(xhrBackend, requestOptions, router, injector);
}
export function customErrorHandler(injector) {
return new CustomErrorHandler(injector);
}
@NgModule({
declarations: [
...
],
imports: [
...
],
providers: [
{ provide: Http, useFactory: customHttpServiceFactory, deps: [XHRBackend, RequestOptions, Router, Injector] },
// { provide: UrlSerializer, useClass: LowercaseUrlSerializer },
{ provide: ErrorHandler, useFactory: customErrorHandler, deps: [Injector] },
...
],
bootstrap: [AppComponent]
})
export class AppModule {}