我已经用Angular构建了一个基本的应用程序,但是我遇到了一个奇怪的问题,我不能将服务注入到我的一个组件中。但是,它可以很好地注入我创建的其他三个组件。

对于初学者来说,这是服务:

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

@Injectable()
export class MobileService {
  screenWidth: number;
  screenHeight: number;

  constructor() {
    this.screenWidth = window.outerWidth;
    this.screenHeight = window.outerHeight;

    window.addEventListener("resize", this.onWindowResize.bind(this) )
  }
  
  onWindowResize(ev: Event) {
    var win = (ev.currentTarget as Window);
    this.screenWidth = win.outerWidth;
    this.screenHeight = win.outerHeight;
  }
  
}

以及它拒绝使用的组件:

import { Component, } from '@angular/core';
import { NgClass } from '@angular/common';
import { ROUTER_DIRECTIVES } from '@angular/router';

import {MobileService} from '../';

@Component({
  moduleId: module.id,
  selector: 'pm-header',
  templateUrl: 'header.component.html',
  styleUrls: ['header.component.css'],
  directives: [ROUTER_DIRECTIVES, NgClass],
})
export class HeaderComponent {
  mobileNav: boolean = false;

  constructor(public ms: MobileService) {
    console.log(ms);
  }

}

我在浏览器控制台得到的错误是这样的:

EXCEPTION:不能解析HeaderComponent:(?)的所有参数。

我在bootstrap函数中有服务,所以它有一个提供者。而且我似乎能够将它注入到任何其他组件的构造函数中而没有任何问题。


当前回答

明白了!

如果以上答案都对您没有帮助,那么您可能正在从组件注入服务的同一个文件中导入某个元素。

我解释得更好:

这是服务文件:

// your-service-file.ts
import { helloWorld } from 'your-component-file.ts'

@Injectable()
export class CustomService() {
  helloWorld()
}

这是组件文件:

@Component({..})
export class CustomComponent {
  constructor(service: CustomService) { }
}

export function helloWorld() {
  console.log('hello world');
}

因此,即使符号不在同一个组件中,而只是在同一个文件中,也会引起问题。将符号(可以是函数、常量、类等等)移动到其他地方,错误就会消失

其他回答

从Angular 2.2.3开始,现在有了一个forwardRef()实用函数,它允许你注入尚未定义的提供程序。

所谓没有定义,我的意思是依赖注入映射不知道标识符。这就是循环依赖关系期间发生的情况。在Angular中,你可能会有循环依赖关系,它们很难理清和观察。

export class HeaderComponent {
  mobileNav: boolean = false;

  constructor(@Inject(forwardRef(() => MobileService)) public ms: MobileService) {
    console.log(ms);
  }

}

在原始问题的源代码中,将@Inject(forwardRef(() => MobileService)添加到构造函数的参数将解决这个问题。

参考文献

Angular 2手动:ForwardRef

Angular 2中的正向引用

对我来说,这是因为我停止使用-aot标志,同时试图使编译时间更快。

 ng serve -aot

为了搜索者的利益;我得到了这个错误。这只是一个丢失的@符号。

也就是说,这会产生无法解析MyHttpService的所有参数的错误。

Injectable()
export class MyHttpService{
}

添加缺少的@符号可以修复它。

@Injectable()
export class MyHttpService{
}

由于错误中缺乏反馈,这可能是一个非常难以调试的问题。如果你关心一个实际的循环依赖,这里是在堆栈跟踪中最重要的东西:a)服务的名称;b)该服务中带有问号的构造函数参数,例如,如果它看起来像这样:

无法解析AuthService的所有参数([object object]) [object object], [object object], [object object], ?

那么它意味着第五个参数也是一个依赖于AuthService的服务。即问号,表示未被DI解决。

从这里开始,您只需要通过重新构造代码来解耦这两个服务。

对我来说,这个问题甚至更烦人,我正在使用服务中的服务,忘记在appModule中添加它作为依赖项! 希望这能帮助一些人节省几个小时的应用程序分解,只是重新建立它