Angular 角度不';我看不到注入服务

Angular 角度不';我看不到注入服务,angular,error-handling,components,Angular,Error Handling,Components,我想为错误处理程序创建一种拦截器。这就是我创建这些文件的原因: 错误服务: import { Injectable } from '@angular/core'; @Injectable() export class ErrorService { name : any; constructor() { } setName(message:string){ this.name = messa

我想为错误处理程序创建一种拦截器。这就是我创建这些文件的原因:

错误服务:

import { Injectable } from '@angular/core';

    @Injectable()
    export class ErrorService {
       name : any;

        constructor() {
        }

        setName(message:string){
            this.name = message;
        }

        getName(){
            return this.name;
        }

        error(detail: string, summary?: string): void {
            this.name = detail;
        }
    }
AppErrorHandler:

import { ErrorService } from './error-service';
import { ErrorHandler, Inject  } from '@angular/core';


export class AppErrorHandler implements ErrorHandler {

    constructor(@Inject(ErrorService) private errorService: ErrorService){

    }

    handleError(error : any){
        this.errorService.setName(error.status);
        console.log('getter', this.errorService.getName());
        console.log('test error ', error);        
    }    
}
在这一点上,一切都很顺利。当我在
handleError
中打印错误时,它会正确打印

但是当我想将
ErrorService
对象传递到
ErrorComponent
时,Angulas突然看不到它

错误组件:

import { ErrorService } from './../common/error-service';
import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'error',
  templateUrl: './error.component.html',
  styleUrls: ['./error.component.css']
})
export class ErrorComponent implements OnInit {

  constructor(private errorService: ErrorService) {
    console.log('from ErrorComponent, ', this.errorService);
  }

  message = this.errorService.getName();


  ngOnInit() {
  }

}
和ErrorComponent.html

<div class="alert alert-danger">
  Error!!! {{message}}
</div>

问题在于,在
AppErrorHandler
中,我正在将错误传递给
ErrorService
,我想在
ErrorComponent
中显示它,但
ErrorComponent
没有看到传递的数据

更新: 我遵循下面的解决方案,得到了一个错误。我的
errorComponent
看起来像:

import { ErrorService } from './../common/error-service';
import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'error',
  templateUrl: './error.component.html',
  styleUrls: ['./error.component.css']
})
export class ErrorComponent implements OnInit {
  errorService: ErrorService;
  message: string;

  constructor(errorService: ErrorService) {
    this.errorService = errorService;
    console.log('------ from error component ', errorService.name, this.errorService);
  }

  ngOnInit() {
  }

}
以及
html
文件:

<div class="alert alert-danger">
  Error!!! {{errorService.name}}
</div>

错误{{errorService.name}
问题是我无法在浏览器中打印name属性。在chrome控制台中,我有:


所以您可以看到,我可以很容易地获取整个对象ErrorService,但无法获取控制台中未定义的属性名,这是为什么?因此,我无法正确显示它。

您可能需要使用
forwardRef()


以下是如何解决您的问题:

1) 为了能够有效地将
ErrorService
注入
AppErrorHandler
,您需要使用
Injectable()
装饰
AppErrorHandler
。这样,您就可以删除
@Inject(ErrorService)
,只需以标准方式注入服务

import { ErrorService } from './error-service';
import { ErrorHandler, Injectable  } from '@angular/core';

@Injectable()
export class AppErrorHandler implements ErrorHandler {

    constructor(private errorService: ErrorService){}   
}
2) 在
AppErrorHandler
中,您的目标是错误对象的属性
status
。请记住,标准错误对象具有诸如
消息
名称
说明
编号
等属性,具体取决于浏览器。在尝试获取属性的值之前,您可能需要检查
status
属性是否存在,否则对于非HTTP错误,您可能会获取
undefined

更新:确保调用
super(true)
super.handleError(错误)
抛出错误
以确保重新抛出错误,并在自定义错误处理之后进行默认错误处理。否则,这些错误将被自定义错误处理程序接受

导出类AppErrorHandler实现ErrorHandler{

// ...

handleError(error : any) {
    // rethrow exceptions
    super(true);

    if(error.status) {
        console.log(error.status);
        this.errorService.setName(error.status);
    }
    else {
        console.log('Message: ', error.message);  
        console.log('Description: ', error.description);
        this.errorService.setName(error.message);
    }

    console.log('Getter: ', this.errorService.getName());

    // trigger default error handling after custom error handling
    super.handleError(error);
}    
}

3) 在错误组件中,要主动查看对
ErrorService
name
属性的更改,至少要将
name
属性设置为公共属性。然后在ErrorComponent中,您将目标对准注入服务的
name
属性来显示。一种更具伸缩性的方法是使用RxJS主题,例如发出
ErrorComponent
可以订阅的更改。Doing
message=this.errorService.getName()在发生错误时不会自动重置/响应对名称属性的更改。您需要附加到公共属性和/或使用observables或类似工具来向要订阅的组件发出更改。有关如何利用RxJS进行更新的示例,请参见下面的更新2

服务:

import { Injectable } from '@angular/core';

@Injectable()
export class ErrorService {
   public name : any;

   constructor() {}
错误组件HTML

<div class="alert alert-danger">
  <!-- Angular will detect changes to the services' -->
  Error!!! {{errorService.name}}
</div>
这里是一个更新的


希望这有帮助

问题出在哪里??您会遇到什么类型的错误?在将
ErrorService
注入
AppErrorHandler
时,不要使用
@Inject
@Inject用于基本值/类型。只需执行
构造函数(私有errorService:errorService){}
。看看这是否有区别。问题是在
AppErrorHandler
中,我正在将错误传递给
ErrorService
,我想在
ErrorComponent
中显示它,但
ErrorComponent
没有看到传递的错误data@AlexanderStaroselsky当我删除它时,浏览器中出现错误:
compiler.es5.js:1690未捕获错误:无法解析AppErrorHandler:(?)的所有参数。
您的代码似乎正常工作,请查看我的更新。我已经按照你的指示做了,但我遇到了一个关键的错误。您能帮助我吗?当
ErrorComponent
中的
constructor()
运行时,没有为
ErrorService
中的属性
name
分配错误,因为它没有默认值。这就是为什么当您尝试记录时,
name
是未定义的。我已经更新了日志记录前后的显示
errorService.name
。如果您想要
name
的默认值,在
ErrorService
中,您可以执行类似于
public name:string='foobar'
的操作,否则在
构造函数()
时,它将是
未定义的<代码>错误服务
在主模块中导入时实际上是单例的。这不是我问题的答案。我提到我的errorService名称的原因并不是因为我想给它分配一些文本,比如“foobar”。原因是我想分配给变量errorService http错误状态-例如,500、403、404。我有一个例子,我调用了故意错误,我在控制台中看到它,就像我的更新一样。但我的想法是,我无法将
errorService.name
中的变量
message
(位于
error component
中)分配给该变量。您向我展示的是将随机文本分配给
errorService.name
,这不是我的目标。将值分配给
errorService.name
位于
错误处理程序中,看起来像:
handleError(错误:any){this.errorService.name=error.status;
和来自
errorService
的变量
name
我想在
错误组件中显示该变量
name
import { Injectable } from '@angular/core';

@Injectable()
export class ErrorService {
   public name : any;

   constructor() {}
<div class="alert alert-danger">
  <!-- Angular will detect changes to the services' -->
  Error!!! {{errorService.name}}
</div>
@Injectable()
export class ErrorService {
  public name: string;

  // create new Subject
  private nameSource = new Subject<any>();

  // expose Observable property
  error$ = this.nameSource.asObservable();

  setName(message: string){
    this.name = message;
    // emit error
    this.nameSource.next(this.name);
  }

  // ...
}

@Component({ // ... })
export class ErrorComponent {
  message: string = '';

  constructor(private errorService: ErrorService) {
    // same stuff as before

    // subscribe to Observable from ErrorService and update name property on changes
    this.errorService.error$.subscribe(name => {
      this.message = name;
    });
  }
}

@Injectable()
export class AppErrorHandler extends ErrorHandler {
    private errorService: ErrorService;

    constructor(errorService: ErrorService) {
      super(true);
      this.errorService = errorService;
      console.log(this.errorService);
    }

    handleError(error : any) {
        if(error.status) {
            console.log(error.status);
            this.errorService.setName(error.status);
        }
        else {
            console.log('Message: ', error.message);  
            console.log('Description: ', error.description);
            this.errorService.setName(error.message);
        }
    }    
}