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


当前回答

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

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

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

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

其他回答

问题是,模块中的元素应该对属于同一模块的元素使用相对导入;它们永远不应该通过模块的公共API桶(或一般的桶)导入。

该导入的问题是,如果依赖于服务的某些东西首先在桶中加载(直接或不直接),那么DI系统将失败,因为服务还没有声明,因此无法解决。

尝试从absolute更改import:

import { UserService } from 'src/app/users/user.service';

相对:

import { UserService } from '../../users/user.service';

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

export class ProductComponent {
    productList: Array<Product>;

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

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

在引用接口时也会发生这种情况。

改变类的接口修复了它,使用和不使用@Inject。

如前所述,这个问题是由桶内的导出排序引起的,而桶内的导出排序是由循环依赖关系引起的。

更详细的解释在这里:https://stackoverflow.com/a/37907696/893630

如果你试图注入一个接口,也会发生这个错误:

的地方:

export const MY_SERVICE = new InjectionToken<MyService>('MY_SERVICE');

export interface MyService {
  // ...
}

@Injectable()
export class MyServiceImpl implements MyService {
  // ...
}

不正确的:

  constructor(
    private myService: MyService
  ) {}

正确的:

  constructor(
    @Inject(MY_SERVICE) private myService: MyService
  ) {}