48 votes

Comment partager le service entre deux modules - @NgModule angulaire et non entre composants?

Dans mon application, j'ai deux différents bootstrap module (@NgModule) fonctionnant de façon autonome dans une seule application. Il n'y a pas un seul angulaire app peu distincte bootstrap module et maintenant je veux qu'ils doivent communiquer les uns aux autres et de partager des données.

Je le sais par @Injectable service en tant que fournisseur dans le module, je peux partager des données dans tous les composants, en vertu @NgModule mais comment je vais partager des données entre deux module ( pas de composants à l'intérieur du module ).

Est-il un moyen un objet de service peut être consulté dans un autre module? Est il possible que je peux accéder à l'objet de Service disponible dans le navigateur de la mémoire et de l'utiliser dans mes autres angulaire module?

57voto

FacelessPanda Points 601

Comme pour la version finale Angulaire 2, les services fournis par un module sont disponibles pour tous les autres modules qui l'importe. Le Style Officiel Guide de conseils que l'ensemble de l'application services (singletons) qui doivent être réutilisé n'importe où dans la demande doivent être fournies par certains Core Module, pour être importé dans le principal App Module de sorte qu'il serait injectable partout.

Si vous n'utilisez pas une structure qui comporte un Module de Base avec un partage des singletons, et vous êtes indépendamment du développement de deux NgModules, et que vous voulez un service à l'un d'entre eux à être utilisé dans l'autre, alors la seule solution est d'importer le fournisseur dans l'autre :

Voici le fournisseur de module:

/// 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 devrait être injectable dans un composant SomeOtherModule déclare, et dans SomeModule lui-même - il suffit de demander pour elle 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 ce n'est pas la réponse à votre question, je vous invite à re-formuler.

21voto

Hager Aly Points 726
  1. créer des modules partagés

    @NgModule({}) export class SharedModule { static forRoot(): ModuleWithProviders { return { ngModule: SharedModule, providers: [SingletonService] }; } }

  2. dans l'application du module sont vos parents app module importer le module partagé comme ça

    SharedModule.forRoot()

  3. tous les enfants des modules si vous avez besoin d'importer le module partagé l'importer sans le root

    SharedModule

https://angular-2-training-book.rangle.io/handout/modules/shared-modules-di.html

11voto

Günter Zöchbauer Points 21340

Vous pouvez instancier un service à l'extérieur Angulaire et de 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 une demande de modification de l'état en SharedService ou appelle une méthode qui provoque une 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ée dans l' NgZone de l'émetteur.

Par conséquent, lors de la souscription à une observable en SharedService d'utilisation

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?

3voto

Ryan Anderson Points 41

La réponse donnée par Günter Zöchbauer est excellente. Cependant, un problème que vous pouvez avoir est que

 window.sharedService
 

provoquera une erreur dans TypeScript. Vous pouvez contourner ce problème en remplaçant toutes les instances de

 window.sharedService
 

avec

 (<any>window).sharedService
 

2voto

birwin Points 1248

J'ai tenté d'utiliser les idées de cette réponse pour partager des données entre plusieurs bootstrap modules dans mon angulaire de l'application. Les données que j'étais intéressé en était venue à partir d'une adresse http.get() de l'appel. C'était un appel coûteuse, et je voulais seulement faire l'appel une fois et de partager les résultats entre mes 2 bootstrap modules.

D'abord, j'ai stocké le service de la propriété de ma fenêtre globale de l'objet, comme l'a suggéré, mais à la fin, j'ai décidé d'utiliser des variables statiques et appel publishReplay() sur mon observables pour créer un ReplaySubject à relire mes émissions pour les futurs abonnés. Cela a permis à plusieurs abonnés de partager des données et faire seulement de l'appel RESTE une fois.

Une mise en garde ici... La question initiale posée de savoir comment partager un service... Cette réponse ne partage pas un service... de Multiples services sont créés, mais les données sont partagées comme l'observable est stockée dans une variable statique... cela signifie Que les observables autour de bâtons tant que votre application et la raison de l'appel à publishReplay() toute personne qui s'abonne à la observables relit les données précédemment retourné.

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.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X