我已经用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函数中有服务,所以它有一个提供者。而且我似乎能够将它注入到任何其他组件的构造函数中而没有任何问题。


当前回答

你必须在@Component decorator中或在组件声明的模块中添加providers数组。在组件内部,你可以这样做:

@Component({
  moduleId: module.id,
  selector: 'pm-header',
  templateUrl: 'header.component.html',
  styleUrls: ['header.component.css'],
  directives: [ROUTER_DIRECTIVES, NgClass],
  providers: [MobileService]
})

其他回答

在我的例子中,发生这种情况是因为我没有声明构造函数形参的类型。

我有这样的东西:

constructor(private URL, private http: Http) { }

然后将其更改为下面的代码解决了我的问题。

constructor(private URL : string, private http: Http) {}

在我的例子中,将错误的参数传递给构造函数会产生这个错误,关于这个错误的基本思想是,你在不知不觉中传递了一些错误的参数给任何函数。

export class ProductComponent {
    productList: Array<Product>;

    constructor(productList:Product) { 
         // productList:Product this arg was causing error of unresolved parameters.
         this.productList = [];
    }
}

我通过去掉这个参数来解决这个问题。

除了缺少@Injectable()装饰器之外

抽象类中缺少@Injectable()装饰器会产生Can't resolve all parameters for service:(?) 装饰器需要出现在MyService和派生类BaseService中

//abstract class
@Injectable()
abstract class BaseService { ... }

//MyService    
@Injectable()
export class MyService extends BaseService {
.....
}

当你在app.module.js中声明Angular的内置模块(HttpClientModule, HttpErrorResponse等)时,有时会发生这种情况。我也遇到过同样的问题,但现在解决了。

我犯的错误是提到HttpClientModule into Providers而不是Import of angular Module

从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中的正向引用