【问题标题】:Angular2 - How do I inject a service into a custom exception handlerAngular2 - 如何将服务注入自定义异常处理程序
【发布时间】:2016-08-03 04:27:20
【问题描述】:

我有一个像这样的自定义异常处理程序,我试图在其中注入服务 (ErrorReportingService)

import { ExceptionHandler, Injectable } from '@angular/core';
import {ErrorReportingService  } from '../services/ErrorReportingService';

@Injectable()
export class InsightsExceptionHandler extends ExceptionHandler {
    constructor(private _errorReporter: ErrorReportingService) {
        super(null, null);
    }

call(error, stackTrace = null, reason = null) {
    this._errorReporter.logError(error);

    }
}

我尝试注入的服务如下所示

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

@Injectable()
export class ErrorReportingService {
    private ErrorReportingUrl = `/property/insights/api/errorreporting`;
    constructor(private _http: Http) { }

    logError(error: any) {
        var body = JSON.stringify(error);
        this._http.post(this.ErrorReportingUrl, body, null);
    }
}

ErrorReportingService 注册在应用组件的 providers 下。

我也尝试过像这样以不同的方式注入服务:

export class InsightsExceptionHandler extends ExceptionHandler {
    private _errorReporter: ErrorReportingService;
    constructor( @Inject(ErrorReportingService) errorReporter: ErrorReportingService) {
        super(null, null);
        this._errorReporter = errorReporter;
    }
......

我在尝试运行应用程序时收到此错误:

Error: (SystemJS) EXCEPTION: Error during instantiation of ApplicationRef_! (ApplicationRef -> ApplicationRef_).
ORIGINAL EXCEPTION: No provider for ErrorReportingService! (ExceptionHandler -> ErrorReportingService)
ORIGINAL STACKTRACE:
Error: DI Exception

【问题讨论】:

    标签: angular dependency-injection angular2-services angular2-injection


    【解决方案1】:

    我猜在您引导应用程序的应用程序主文件中,您必须使用类似于下面的内容进行异常处理,

    在引导提供程序本身中添加您需要的所有服务,

    bootstrap(
    <YourAppComponent>,
    [
        // inject all the services which you need here 
        // so that they can be injected wherever required
    
        ErrorReportingService,
        provide(ExceptionHandler, {
            useClass: InsightsExceptionHandler 
        })
    ]).catch(err => console.error(err));
    

    【讨论】:

    • 谢谢,这成功了。虽然我不明白为什么我必须在引导调用中提供它们,因为它们已经在 App 组件的提供者中?
    • 我们通过在引导程序中注册一个提供程序来覆盖默认的 Angular ExceptionHandler,并且 Angular 会根据它的注册位置决定何时创建服务,所以在这种情况下是在引导程序中,所以它会搜索同一级别的所有依赖项,尽管您可能在 App 组件中添加了 ErrorReportingService 提供程序,该提供程序将为 App 组件或子组件创建一个新的 ErrorReportingService 实例。希望这会有所帮助!
    【解决方案2】:

    要打破循环使用

    @Injectable()
    export class ErrorReportingService {
      constructor(injector:Injector) {
        setTimeout(() {
          this.appRef = injector.get(ApplicationRef);
        });
      }
    }
    

    我不知道这是否正是导致循环的原因,因为您的问题不包含 ErrorReportingService 来源,但您应该明白这一点。

    【讨论】:

    • 谢谢,我试过了,但它对我不起作用——同样的错误。服务的来源在问题中。
    • 哦,不知怎的,我错过了。可能对ApplicationRef 有一些间接依赖。尝试像我在答案中使用ApplicationRef 那样注入Http
    • 这就是我尝试过的。我想知道如果我阅读并尝试了您之前建议的方式,角度是否发生了变化,我总是遇到问题中提到的相同错误。
    • 我想我需要一个笨蛋来调查。
    猜你喜欢
    • 2015-12-05
    • 1970-01-01
    • 2021-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-13
    • 2015-10-18
    相关资源
    最近更新 更多