Comment partager le service entre deux modules - @NgModule en angle et non entre les composants?
dans mon application, j'ai deux modules bootstrap différents ( @NgModule
) fonctionnant indépendamment dans une application. Il n'y a pas un seul bit d'application angulaire séparé module bootstrap et maintenant je veux qu'ils doivent communiquer entre eux et partager des données.
je sais à travers le service @Injectable
en tant que fournisseur dans le module, je peux partager des données dans tous les composants sous @NgModule
mais comment je vais partager des données entre deux modules différents ( pas composante à l'intérieur du module ).
y a-t-il un moyen d'accéder à un objet de service dans un autre module? Y a-t-il un moyen d'accéder à l'objet de Service disponible dans la mémoire du navigateur et de l'utiliser dans mon autre module angulaire?
5 réponses
vous pouvez instancier un service en dehors D'Angular et fournir une valeur:
class SharedService {
...
}
window.sharedService = new SharedService();
@NgModule({
providers: [{provide: SharedService, useValue: window.sharedService}],
...
})
class AppModule1 {}
@NgModule({
providers: [{provide: SharedService, useValue: window.sharedService}],
...
})
class AppModule2 {}
Si l'on demande de changer l'état en SharedService
ou appelle une méthode qui provoque un Observable
d'émettre une valeur et l'abonné est dans une application différente de celle de l'émetteur, le code de l'abonné est exécuté dans le NgZone
de l'émetteur.
donc en souscrivant à un observable dans SharedService
utiliser
class MyComponent {
constructor(private zone:NgZone, private sharedService:SharedService) {
sharedService.someObservable.subscribe(data => this.zone.run(() => {
// event handler code here
}));
}
}
Voir aussi Comment créer dynamiquement des fichiers d'amorce des modaux comme Angular2 composants?
selon la version finale D'Angular 2, les services fournis par un module sont disponibles pour tous les autres modules qui l'importent.
Le Guide de Style officiel conseil que les services à l'échelle de l'application (singletons) qui doivent être réutilisés n'importe où dans l'application devrait être fourni par quelque Core Module
, qui doit être importé dans le principal App Module
de sorte qu'il serait injectable partout.
si vous n'utilisez pas une structure qui implique un noyau Module avec singletons partagés, et vous développez indépendamment deux NgModules, et vous voulez un service dans l'un d'eux pour être utilisé dans l'autre, alors la seule solution est d'importer le fournisseur dans l'autre:
voici le module fournisseur:
/// some.module.ts
import { NgModule } from '@angular/core';
import { SomeComponent } from './some.component';
@NgModule({
imports: [],
exports: [],
declarations: [SomeComponent],
providers: [ MyService ], // <======================= PROVIDE THE SERVICE
})
export class SomeModule { }
Voici l'autre module, qui veut utiliser MyService
/// some-other.module.ts
import { NgModule } from '@angular/core';
import { SomeModule } from 'path/to/some.module'; // <=== IMPORT THE JSMODULE
import { SomeOtherComponent } from './some.other.component';
@NgModule({
imports: [ SomeModule ], // <======================== IMPORT THE NG MODULE
exports: [],
declarations: [SomeOtherComponent],
providers: [],
})
export class SomeOtherModule { }
de cette façon, le service doit être injectable dans n'importe quel composant SomeOtherModule
déclare, et dans SomeModule lui - même-il suffit de le demander dans le constructeur:
/// some-other.module.ts
import { MyService } from 'path/to/some.module/my-service';
/* ...
rest of the module
*/
export class SomeOtherModule {
constructor( private _myService: MyService) { <====== INJECT THE SERVICE
this._myService.dosmth();
}
}
si cela ne répond pas à votre question, je vous invite à le reformuler.
-
créer un module partagé
@NgModule({}) export class SharedModule { static forRoot(): ModuleWithProviders { return { ngModule: SharedModule, providers: [SingletonService] }; } }
-
dans le module app sont votre module app parent importer le module partagé comme cela
SharedModule.forRoot()
-
tous les modules enfants si vous avez besoin d'importer le module partagé importer sans la racine
SharedModule
https://angular-2-training-book.rangle.io/handout/modules/shared-modules-di.html
la réponse que Günter Zöchbauer a donnée est grande, cependant, une question que vous pouvez avoir est que
window.sharedService
causera une erreur de frappe. Vous pouvez contourner cela en remplaçant toutes les instances de
window.sharedService
avec
(<any>window).sharedService
j'ai essayé d'utiliser les idées dans cette réponse pour partager des données entre plusieurs modules bootstrapped dans mon application angulaire. Les données qui m'intéressaient venaient d'un http.get() de l'appel. C'était un appel coûteux et je voulais seulement faire l'appel une fois et partager ses résultats entre mes 2 modules bootstrapped.
initialement, j'ai stocké le service comme une propriété sur mon objet global window comme suggéré, mais à la fin, j'ai décidé d'utiliser des variables statiques et d'appeler publishReplay() sur mon observables pour créer un ReplaySubject à relire mes émissions pour les futurs abonnés. Cela permettait à plusieurs abonnés de partager des données et de ne faire le reste de l'appel qu'une seule fois.
un avertissement... La question initiale demandait comment partager un service... Cette réponse ne partage pas un service... Plusieurs services sont créés, mais les données sont partagées car l'observable est stocké dans une variable statique... Cela signifie que l'observable reste aussi longtemps que votre application et en raison de l'appel à publishReplay()
toute personne qui s'abonne à l'observable rejoue les données précédemment retournées.
Voici mon code:
import { Injectable } from '@angular/core';
import { Observable, ReplaySubject } from 'rxjs/Rx';
import { Http } from '@angular/http';
@Injectable()
export class InitService {
static observable: Observable<number> = null;
constructor(private http: Http) {}
getInitData(): Observable<number> {
if (InitService.observable == null) {
InitService.observable = this.http.get('api/Init')
.map(this.extractData)
.publishReplay()
.refCount()
.catch(this.handleError);
}
return InitService.observable;
}
extractData(res: Response) {
let body: any = res.json();
return body || {};
}
}
Espérons que cette aide.