web-dev-qa-db-ja.com

Angular 2:(注入された)サービスのプロバイダーなし

アプリには、MainServiceとRightClickServiceの2つのサービスがあります。 MainServiceのみがアプリケーションでグローバルにアクセス可能であり、RightClickServiceがMainServiceに注入されます。したがって、次のファイルを次のように定義しました。

app.module.ts

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

RightClickServiceはapp.module.tsには記載されていません。

service.ts

 @Injectable()
 export class MainService {

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

RightClickServiceは、大きなアプリケーションRightClickComponent内で名前が付けられた1つのコンポーネントにのみ存在します。

right-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!

私が間違っていることを知っていますか?

17
CrazySynthax

既に述べたことに加えて、次の2つのことを知っておく必要があります。

  1. アプリには、AppModuleを含むアプリ内のモジュールの@NgModule.providers配列で削除されたすべてのプロバイダーを含むルートインジェクターが1つしかありません。

  2. 各コンポーネントには、コンポーネントの@Component.providers配列で宣言されたプロバイダーを含む独自のインジェクター(ルートインジェクターの子インジェクター)があります。

when angular service(MainService)の依存関係(RightClickService)を解決したい場合、すべてのNgModuleのプロバイダーを含むルートインジェクターで検索します。

angular component(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 { }

私はこれをPlunkerに入れただけで、何かをタイプミスしない限り...あなたが持っているものはうまくいくようです。それで、何か他のものが間違っているのでしょうか?

ここでプランカーを確認できますか? https://plnkr.co/edit/ea9dFs?p=info

(このツールでは、コードなしで投稿することはできませんが、上記のコードは既にあるので、その一部を貼り付けています。)

import { Injectable } from '@angular/core'

 @Injectable()
 export class RightClickService {

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