Angular2 – Condividi i dati tra componenti utilizzando i servizi

Ho un object che voglio condividere tra i miei componenti in un’app Angular2.

Ecco la fonte del primo componente:

/* app.component.ts */ // ...imports import {ConfigService} from './config.service'; @Component({ selector: 'my-app', templateUrl: 'app/templates/app.html', directives: [Grid], providers: [ConfigService] }) export class AppComponent { public size: number; public square: number; constructor(_configService: ConfigService) { this.size = 16; this.square = Math.sqrt(this.size); // Here I call the service to put my data _configService.setOption('size', this.size); _configService.setOption('square', this.square); } } 

e il secondo componente:

 /* grid.component.ts */ // ...imports import {ConfigService} from './config.service'; @Component({ selector: 'grid', templateUrl: 'app/templates/grid.html', providers: [ConfigService] }) export class Grid { public config; public header = []; constructor(_configService: ConfigService) { // issue is here, the _configService.getConfig() get an empty object // but I had filled it just before this.config = _configService.getConfig(); } } 

e infine il mio piccolo servizio, il ConfigService:

 /* config.service.ts */ import {Injectable} from 'angular2/core'; @Injectable() export class ConfigService { private config = {}; setOption(option, value) { this.config[option] = value; } getConfig() { return this.config; } } 

I miei dati non sono condivisi, nel grid.component.ts, la _configService.getConfig() restituisce un object vuoto, ma è stato riempito poco prima in app.component.ts.

Ho letto i documenti e le esercitazioni, niente ha funzionato.

Cosa mi manca?

Grazie

RISOLTO

Il mio problema era che stavo iniettando il mio ConfigService due volte. Nel bootstrap dell’applicazione e nel file in cui lo sto usando.

Ho rimosso l’impostazione dei providers e il suo funzionamento!

Lo si definisce all’interno dei due componenti. Quindi il servizio non è condiviso. Si dispone di un’istanza per il componente AppComponent e un’altra per il componente Grid .

 @Component({ selector: 'my-app', templateUrl: 'app/templates/app.html', directives: [Grid], providers: [ConfigService] }) export class AppComponent { (...) } 

La soluzione rapida consiste nel rimuovere l’attributo providers nel componente Grid … In questo modo l’istanza del servizio verrà condivisa da AppComponent e dai relativi componenti AppComponent .

L’altra soluzione è registrare il provider corrispondente all’interno della funzione bootstrap . In questo caso, l’istanza sarà condivisa dall’intera applicazione.

 bootstrap(AppComponent, [ ConfigService ]); 

Per capire perché è necessario farlo, è necessario essere consapevoli della funzione “Iniettori gerarchici” di Angular2. I seguenti collegamenti potrebbero essere utili:

Per l’ultima versione di angular, se si desidera condividere il servizio, non è ansible aggiungerlo alla funzione bootstrap. Basta aggiungerlo all’elenco dei provider NgModule come faresti con un servizio normale, il suo comportamento predefinito sarà singleton.

bootstrap (AppComponent);

 @NgModule({ declarations: [ .... ], imports: [ .... ], providers: [ ConfigService, .... 

Non aggiungere ConfigService ai providers del componente. Ciò si traduce in nuove istanze per ogni componente. Aggiungilo ai providers di un componente genitore comune. Se lo aggiungi al tuo componente root o bootstrap(App, [ConfigService]) l’intera applicazione condivide una singola istanza.