Je viens de rencontrer un problème avec un module paresseux où les modules parent et enfant nécessitent tous deux le même service mais créent chacun une instance. 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 procéder si je souhaite partager la même instance de service?
L'utilisation d'un forRoot
, comme mentionné ici , est probablement ce dont vous avez besoin. Le problème qu'il est censé résoudre est directement lié au problème que vous rencontrez avec les modules chargés paresseux obtenant leur propre service.
Il est expliqué ici dans Configurer les services principaux avec forRoot
, mais cette section n'explique pas le problème du chargement paresseux. Cela s'explique par un petit avertissement à la fin de modules partagés
Ne spécifiez pas de singleton à l'échelle de l'application
providers
dans un module partagé. Un module chargé paresseusement qui importe ce module partagé 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 garantit que le module chargé paresseusement n'obtient pas le service. Mais que le module soit ou non chargé paresseusement, c'est le modèle qui est recommandé pour les services à l'échelle de l'application. Bien qu'il soit à noter que si vous n'avez pas de module chargé paresseusement, n'utilisez pas le patter forRoot
et importez simplement SharedModule
, ce ne sera qu'une seule instance du service. Mais ce schéma devrait tout de même être recommandé.
Je suppose que je suis allé trop vite pour répondre sans regarder complètement la question. Dans la question, il n'y a est aucune mention d'un module partagé. Il semble que l'OP essaie simplement d'ajouter le service au @NgModule.providers
dans le module d'application et le module enfant chargé paresseux.
Dans ce cas, supprimez simplement le service du module enfant providers
. Ce n'est pas nécessaire. Celui ajouté dans le module d'application suffit pour que l'enfant soit utilisé.
N'oubliez pas que providers
est à l'échelle de l'application (sauf dans le cas problématique que ce message concerne), tandis que declarations
ne l'est pas.
Cela devrait fonctionner mais je vous suggère tout de même de choisir le concept SharedModule qui contient common les services, les tuyaux, les directives et les composants .
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: []
});