Angular 2:没有(注入)服务的提供者

时间:2017-03-28 20:35:04

标签: angular dependency-injection

我的应用程序中有两个服务 - MainService和RightClickService。只有MainService可以在应用程序中全局访问,RightClickService将注入MainService。因此,我将以下文件定义为:

app.module.ts

@NgModule({
  declarations: [
    AppComponent,
    ...
  ],
  imports: [
    BrowserModule,
    FormsModule,
    HttpModule
  ],
  providers: [MainService],
  bootstrap: [AppComponent]
})
export class AppModule { }

app.module.ts中未提及RightClickService。

service.ts

 @Injectable()
 export class MainService {

  constructor(private rightClickService: RightClickService) {
    console.log("Constructor is init");
  }
}

RightClickService仅存在于大应用程序RightClickComponent内部命名的一个组件中。

右click.component.ts:

@Component({
  selector: 'right-click',
  template: `
    ...
  `,
  styleUrls: ['...'],
  providers: [RightClickService]
})
export class RightClickComponent implements OnInit {

  constructor(private rightClickService: RightClickService) {}

}

仍然,我收到错误:

EXCEPTION: No provider for RightClickService!

你知道我做错了什么吗?

2 个答案:

答案 0 :(得分:13)

除了已经说过的内容之外,你必须知道两件事:

  1. 您的应用只有一个根注入器,其中包含您应用中任何模块的@NgModule.providers数组中包含的所有提供商,包括AppModule

  2. 每个Component都有自己的注入器(根注入器的子注入器),它包含在组件的@Component.providers数组中声明的提供者。

  3. 当angular要解析服务(MainService)的依赖关系(RightClickService)时,他会在包含所有NgModule提供程序的根注入器中查找它。

    当angular要解析组件(RightClickComponent)的依赖关系(RightClickService)时,他会在组件注入器中查找它,如果找不到,则在中查找它组件注入器如果没有找到,他将做同样的事情,直到他到达根注入器,如果没有发现将抛出错误。

    如果你想解决问题,你可以这样做:

    function MainServiceFactory(RightClickService) {
        return new MainService(new RightClickService());
    }
    
    @NgModule({
      declarations: [
        AppComponent,
        ...
      ],
      imports: [
        BrowserModule,
        FormsModule,
        HttpModule
      ],
      providers: [
       {
         provide: MainService,
         useFactory: MainServiceFactory,
         deps: [RightClickService]
       }
    ],
      bootstrap: [AppComponent]
    })
    export class AppModule { }
    

答案 1 :(得分:4)

我把它拉成了一个Plunker,除非我输入错误的东西......你的东西似乎有效。也许还有其他问题?

你能在这里查看一下那个:https://plnkr.co/edit/ea9dFs?p=info

(该工具不会让我发布没有代码...但你已经有上面的代码...所以我只是粘贴它的一部分。)

import { Injectable } from '@angular/core'

 @Injectable()
 export class RightClickService {

  constructor() {
    console.log("RightClickService is init");
  }
}