Quand utiliser la méthode forRoot() d’Angular

Problème : nous devions partager un service de langage singleton entre tous les modules chargés en différé. J'ai vu la méthode forRoot() et j'ai simplement ignoré sa puissance.

Explication : la méthode forRoot() renvoie un NgModule et ses dépendances de fournisseur.

Dans cet exemple, nous partageons un service pour suivre une valeur de compteur. Chaque fois qu'un composant incrémente la valeur stockée dans le service de compteur, je souhaite partager cela avec tous les composants.

Le problème se pose lorsque vous essayez d'introduire des modules chargés de manière différée. Notez que le composant chargé de manière différée ne partage pas la même valeur de compteur. Lorsque vous utilisez uniquement des composants chargés de manière différée, l'exemple ci-dessous fonctionnera si vous utilisez un service partagé, mais notez comment se comporte le composant chargé de manière différée. Le composant chargé de manière différée obtient sa propre instance du service.

 import { NgModule } from '@angular/core'; import { CounterService } from './counter.service'; @NgModule({ providers: [CounterService], }) export class SharedModule {} 

Voir plunker : https://stackblitz.com/edit/angular-no-for-root-72x3ht?file=app/lazy/lazy.component.ts

Solution : appelez forRoot() dans AppModule et renvoyez un ModuleWithProviders dans sharedModule.

shared.module.ts

 import { NgModule,ModuleWithProviders } from '@angular/core'; import { CounterService } from './counter.service'; @NgModule({ }) export class SharedModule { static forRoot(): ModuleWithProviders { return { ngModule: SharedModule, providers: [ CounterService ] } } } 

app.module.ts

 import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { SharedModule } from './shared/shared.module'; import { AppComponent } from './app.component'; import { EagerComponent } from './eager.component'; import { routing } from './app.routing'; @NgModule({ imports: [ BrowserModule, SharedModule.forRoot(), routing ], declarations: [ AppComponent, EagerComponent ], bootstrap: [AppComponent] }) export class AppModule {} 

Voir Plunker : https://stackblitz.com/edit/angular-no-for-root-yfhkgz?file=app%2Fapp.module.ts

Le service de compteur est désormais partagé entre les modules chargés avec empressement et les modules chargés paresseusement.

Autres lectures recommandées : http://angularfirst.com/the-ngmodule-forroot-convention/

Remarque : je ne recommanderais pas de placer des services partagés et des directives partagées dans le même module.