45 votes

Les modules chargés paresseux peuvent-ils partager la même instance d'un service fourni par leur parent?

Je viens de rencontrer un problème avec un module chargé paresseux où les modules parent et enfant ont tous deux besoin du même service mais créent une instance chacun. La déclaration est identique pour les deux, c’est-à-dire

 import { MyService } from './my.service';
...
@NgModule({
   ...
   providers: [
      MyService,
      ...
   ]
});
 

et voici la configuration de routage

 export parentRoutes: Routes = [
   { path: ':id', component: ParentComponent, children: [
      { path: '', component: ParentDetailsComponent },
      { path: 'child', loadChildren: 'app/child.module#ChildModule' },
      ...
   ]}
];
 

qui, bien sûr, est ensuite importé dans le module parent en tant que

 RouterModule.forChild(parentRoutes)
 

Comment puis-je m'y prendre si je souhaite partager la même instance de service?

59voto

peeskillet Points 32287

À l'aide d'un forRoot, comme mentionné ici, est ce que vous avez besoin probablement. Le problème qu'il doit résoudre, est directement lié à la problématique que vous rencontrez avec lazy modules chargés de l'obtention de leur propre service.

C'est expliqué ici dans Configurer les services de base avec forRoot, mais que l'article n'explique pas sur le lazy-loading question. C'est expliqué avec un peu d'avertissement à la fin de Partagé Modules

Ne spécifiez pas d'application à l'échelle de singleton providers dans un module partagé. Un paresseux module chargé que les importations qui ont partagé module fera sa propre copie du service.

@NgModule({})
class SharedModule {
  static forRoot() {
    ngModule: SharedModule,
    providers: [ MyService ]
  }
}

@NgModule({
  import: [ SharedModule.forRoot() ]
})
class AppModule {}

@NgModule({
  imports: [ SharedModule ]
})
class LazyLoadedModule {}

Cela permet de s'assurer que le paresseux module chargé ne pas obtenir le service. Mais si le module n'est pas chargé ou pas, c'est le modèle qui est recommandé pour une application à l'échelle des services. Mais il convient de noter que si vous n'avez pas de paresseux module chargé, en n'utilisant pas l' forRoot patter, et juste à l'importation SharedModule, il ne sera qu'une instance du service. Mais ce modèle devrait tout de même recommandé d'être suivi.


Mise à JOUR

Je suppose que j'ai sauté rapide sur la manière de répondre sans examiner la question. Dans la question, il n' est pas fait mention d'une quelconque module partagé. Il semble que l'OP est tout simplement d'essayer d'ajouter le service de l' @NgModule.providers dans l'app module et le paresseux enfant chargé de module.

Dans ce cas, il suffit de supprimer le service de l'enfant module providers. Il n'est pas nécessaire. L'on a ajouté dans l'application module est suffisant pour que l'enfant puisse être utilisé.

Juste rappelez-vous que providers sont d'application large (sauf dans le cas de ce poste est d'environ), tandis que l' declarations ne le sont pas.

17voto

micronyks Points 4214

Cela devrait fonctionner, mais je vous conseillerais quand même de choisir le concept SharedModule , qui contient des services, des canaux, des directives et des composants communs .

Shared / SharedModule

 import { NgModule,ModuleWithProviders } from '@angular/core';
import { CommonModule }        from '@angular/common';

import { MyService } from './my.service';

@NgModule({
  imports:      [ CommonModule ],
  declarations: [],
  exports:      [ CommonModule ]
})
export class SharedModule {
  static forRoot(): ModuleWithProviders {
    return {
      ngModule: SharedModule,
      providers: [ MyService ]                       //<<<====here
    };
  }
}
 

AppModule

 import {SharedModule} from './shared/shared.module';
...
@NgModule({
   imports:[ BrowserModule,SharedModule.forRoot()],  //<<<====here
   providers: []
});
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X