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


当前回答

在我的例子中,我对一个没有依赖关系的服务采取了依赖关系,因此我没有向服务类添加constructor()函数。我向依赖的服务类添加了一个无参数构造函数,一切都开始工作了。

其他回答

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

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

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

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

虽然已经提到了从桶中导出类的排序,但下面的场景也可能产生相同的效果。

假设你有类A, B和C从同一个文件中导出,其中A依赖于B和C:

@Injectable()
export class A {
    /** dependencies injected */
    constructor(private b: B, private c: C) {}
}

@Injectable()
export class B {...}

@Injectable()
export class C {...}

因为Angular还不知道依赖类(比如类B和C),(可能是在运行时Angular对类A的依赖注入过程中)就会引发这个错误。

解决方案

解决方案是在执行DI的类之前声明和导出依赖类。

例如,在上面的例子中,类A是在它的依赖关系定义之后声明的:

@Injectable()
export class B {...}

@Injectable()
export class C {...}

@Injectable()
export class A {
    /** dependencies injected */
    constructor(private b: B, private c: C) {}
}

添加Injectable解决了我的问题:

错误代码

import { Observable } from 'rxjs';
import { io } from 'socket.io-client';
import { HttpClient } from '@angular/common/http';

export class Chat {

修复后

import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { io } from 'socket.io-client';
import { HttpClient } from '@angular/common/http';

@Injectable()
export class Chat {

就我而言,原因如下:

我的可注入服务A扩展了另一类B B有一个需要参数的构造函数 我没有在A中定义任何构造函数

因此,在尝试创建对象a时,默认构造函数失败了。我不知道为什么这不是一个编译错误。

我通过在a中添加一个构造函数来解决这个问题,它正确地调用了B的构造函数。

对我来说,当我错误地在填充中禁用此导入时,我得到了这个错误。Ts文件,您需要确保它被导入以避免该错误。

/** Evergreen browsers require these. **/
// Used for reflect-metadata in JIT. If you use AOT (and only Angular decorators), you can remove.
import 'core-js/es7/reflect';