Dans Angular 1, j'ai fréquemment utilisé fabriques pour des services permettant de stocker un état partagé accessible à de nombreux composants. Il semble que, dans Angular 2, tous les services injectés en tant que @Injectable () soient créés à chaque fois, perdant ainsi l’état partagé.
J'enregistre le service sur la clé méta providers
du module racine, mais j'obtiens toujours une instance transitoire.
Ce que j'ai:
Injectable()
export class ArtistService {
constructor(private http:Http) {
// firing on each injection
console.log("ArtistService ctor");
}
}
pour l'appeler dans un composant alors:
@Component({
selector: 'artist-display',
templateUrl: './artistDisplay.html',
})
export class ArtistDisplay {
constructor(private artistService: ArtistService) {
// instance is fine but transient
}
}
Et la définition du module:
@NgModule({
declarations: [...],
imports: [BrowserModule, FormsModule, HttpModule,
RouterModule.forRoot(rootRouterConfig)],
providers : [
ArtistService,
// make sure you use this for Hash Urls rather than HTML 5 routing
{ provide: LocationStrategy, useClass: HashLocationStrategy },
],
bootstrap: [AppComponent]
})
Je soupçonne qu’il existe peut-être un autre moyen d’enregistrer la ArtistService
afin qu’elle reste chargée en tant qu’instance statique? Est-ce possible via DI ou faut-il créer une méthode d'instance statique manuellement?
Mettre à jour:
Il s'avère que le code ci-dessus fonctionne . Je cherchais au mauvais endroit une erreur de logique qui empêchait les données de se mettre en cache correctement.
Le code ci-dessus fonctionne et l'affectation du service dans la section providers
du top level AppModule est la clé pour que la référence parente reste chargée pendant la durée de AppComponent. qui reste effectivement chargé pendant la durée de vie de l'application fournissant le Singleton instance.
Pour obtenir une instance transitoire , vous pouvez déclarer la balise méta providers
et le nom du service sur le composant réel qui créera ensuite le service chaque fois que le composant sera chargé/rechargé.
Ce que vous avez montré est une manière correcte. Il crée une instance unique qui sera partagée entre les composants.
https://plnkr.co/edit/FBCa39YC4ZPoy6y8OZQl?p=preview à des fins de référence.
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import {service} from './service';
@NgModule({
imports: [ BrowserModule ],
declarations: [ AppComponent],
providers:[service],
bootstrap: [ AppComponent ]
})
export class AppModule { }
Je souhaite également créer un objet à utiliser en tant que fournisseur dans angular2. J'ai donc créé un @injecteur . Mais si nous définissons un fournisseur dans chaque composant @ et l'importons, chaque composant utilise un objet différent de injector ..__ en créant un fournisseur singleton, j'ai déclaré ce fournisseur dans le composant parent et l'importer dans chacun d'eux, maintenant tout fonctionne bien. https://angular.io/guide/dependency-injection
Un service Singleton ne doit être conservé que dans app.module.ts "fournisseurs" (tableau)
et il ne doit pas être placé dans un autre composant ou fournisseur de services (baie).
si cela est fait correctement alors angular 2 - 2.4.0 - Singleton fonctionne parfaitement
Ok, laissez-moi essayer d’expliquer comment les services fonctionnent en fonction de mon expérience et de la documentation.
Il y a 3 scénarios principaux:
Le service est inclus dans le groupe de fournisseurs au niveau composant - le service peut être injecté au parent et à tous les enfants.
Le service est inclus dans le groupe de fournisseurs au niveau du module - tout ce que ce module sait sur le service.
Le service est inclus dans le tableau providers au niveau du module - tout le contenu de ce module le connaît, mais si vous utilisez un composant de ce module dans un autre composant d'un autre module qui importe le premier module, l'instance du service de ce composant sois différent.