I moduli lazy-loaded possono condividere la stessa istanza di un servizio fornito dal loro genitore?

Mi sono appena imbattuto in un problema con un modulo lazy-loaded in cui entrambi i moduli padre e figlio richiedono entrambi lo stesso servizio, ma creano un’istanza ciascuno. La dichiarazione è identica per entrambi, cioè

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

ed ecco la configurazione del routing

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

che, ovviamente, viene quindi importato nel modulo genitore come

 RouterModule.forChild(parentRoutes) 

Come faccio a fare questo se volessi condividere la stessa istanza di servizio?

L’uso di un forRoot , come menzionato qui , è quello che ti serve probabilmente. Il problema che si intende risolvere è direttamente correlato al problema che si verifica con i moduli con il carico lento che ricevono il proprio servizio.

È spiegato qui in Configura i servizi di base con forRoot , ma quella sezione non spiega il problema di caricamento lento. Questo è spiegato con un piccolo avvertimento alla fine di Shared Modules

Non specificare i providers singleton a livello di applicazione in un modulo condiviso. Un modulo lazy loaded che importa quel modulo condiviso farà la propria copia del servizio.

 @NgModule({}) class SharedModule { static forRoot() { ngModule: SharedModule, providers: [ MyService ] } } @NgModule({ import: [ SharedModule.forRoot() ] }) class AppModule {} @NgModule({ imports: [ SharedModule ] }) class LazyLoadedModule {} 

Questo assicura che il modulo lazy loaded non ottenga il servizio. Ma indipendentemente dal fatto che il modulo sia o meno pigro o meno, questo è il modello consigliato per i servizi a livello di app. Sebbene si noti che se non si dispone di alcun modulo lazy caricato, non si utilizza il patter forRoot e si importa solo SharedModule , sarà solo un’istanza del servizio. Ma questo modello dovrebbe comunque essere raccomandato per essere seguito.


AGGIORNARE

Immagino di aver risposto rapidamente senza rispondere completamente alla domanda. Nella domanda, non vi è alcuna menzione di alcun modulo condiviso. Sembra che l’OP stia semplicemente tentando di aggiungere il servizio ai @NgModule.providers sia nel modulo app che nel modulo figlio caricato pigro.

In questo caso, è sufficiente rimuovere il servizio dai providers moduli figlio. Non è necessario. Quello aggiunto nel modulo dell’app è sufficiente per il bambino da utilizzare.

Ricorda solo che i providers sono a livello di app (tranne nel caso problematico di cui tratta questo post), mentre le declarations non lo sono.

Questo dovrebbe funzionare, ma suggerisco comunque di andare con il concetto SharedModule che contiene servizi, pipe, direttive e componenti comuni .

Condiviso / 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: [] });