web-dev-qa-db-fra.com

Angular 2: aucun fournisseur de service (injecté)

J'ai deux services dans mon application - MainService et RightClickService. Seul MainService est accessible globalement dans l'application et RightClickService est injecté à MainService. Par conséquent, j'ai défini les fichiers suivants comme suit:

app.module.ts

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

RightClickService n'est pas mentionné dans app.module.ts.

service.ts

 @Injectable()
 export class MainService {

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

RightClickService n'existe que dans un composant nommé dans la grande application RightClickComponent.

clic-droit.component.ts:

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

  constructor(private rightClickService: RightClickService) {}

}

Pourtant, j'ai l'erreur:

EXCEPTION: No provider for RightClickService!

Savez-vous ce que je fais mal?

17
CrazySynthax

En plus de ce qui a déjà été dit, vous devez savoir deux choses:

  1. Votre application ne possède qu'un seul injecteur racine contenant tous les fournisseurs définis dans le tableau @NgModule.providers De tous les modules de votre application, y compris AppModule.

  2. Chaque composant a son propre injecteur (injecteur enfant de l'injecteur racine) qui contient les fournisseurs déclarés dans le tableau @Component.providers Du composant.

quand angular veut résoudre les dépendances (RightClickService) d'un service (MainService), il le cherche dans l'injecteur de racine qui contient les fournisseurs de tous les NgModules.

Lorsque angular souhaite résoudre les dépendances (RightClickService) d'un composant (RightClickComponent), il le recherche dans l'injecteur de composant, s'il n'est pas trouvé, il le recherche dans le parent = composant injecteur s'il n'est pas trouvé, il fera la même chose jusqu'à ce qu'il atteigne l'injecteur de racine s'il n'est pas trouvé, une erreur sera renvoyée.

si vous voulez résoudre le problème, vous pouvez le faire:

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 { }
17

Je viens de tirer ça dans un Plunker, et à moins que je tape mal quelque chose ... ce que tu as semble fonctionner. Alors peut-être qu'il y a quelque chose d'autre qui ne va pas?

Pouvez-vous vérifier le plunker ici: https://plnkr.co/edit/ea9dFs?p=info

(L'outil ne me laissera pas poster sans le code ... mais vous avez déjà le code ci-dessus ... donc je ne fais que coller un morceau de celui-ci.)

import { Injectable } from '@angular/core'

 @Injectable()
 export class RightClickService {

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