Angular2: comparte datos entre componentes usando servicios

Tengo un objeto que quiero compartir entre mis componentes en una aplicación Angular2.

Aquí está la fuente del primer 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); } } 

y el segundo 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(); } } 

y finalmente mi pequeño servicio, 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; } } 

Mis datos no se comparten, en grid.component.ts, la línea _configService.getConfig() devuelve un objeto vacío, pero se llena justo antes en el app.component.ts.

Leí los documentos y tutoriales, nada funcionó.

Qué me estoy perdiendo ?

Gracias

SOLUCIONADO

Mi problema era que estaba inyectando mi ConfigService dos veces. En el arranque de la aplicación y en el archivo donde lo estoy usando.

¡Eliminé la configuración de providers y funcionó!

Lo defines dentro de tus dos componentes. Entonces el servicio no es compartido. Tiene una instancia para el componente AppComponent y otra para el componente Grid .

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

La solución rápida es eliminar el atributo de providers de su componente de cuadrícula … De esta forma, la instancia de servicio será compartida por AppComponent y sus componentes AppComponent .

La otra solución es registrar el proveedor correspondiente dentro de la función de bootstrap . En este caso, la instancia será compartida por toda la aplicación.

 bootstrap(AppComponent, [ ConfigService ]); 

Para entender por qué necesita hacer eso, debe conocer la función de “inyectores jerárquicos” de Angular2. Los siguientes enlaces pueden ser útiles:

Para la última versión de angular, si desea compartir el servicio, no puede agregarlo a la función de arranque. Solo agréguela a la lista de proveedores de NgModule como lo haría con un servicio normal, su comportamiento predeterminado será singleton.

bootstrap (AppComponent);

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

No agregue ConfigService a los providers de su componente. Esto da como resultado nuevas instancias para cada componente. Añádalo a los providers de un componente primario común. Si lo agrega a su componente raíz o al progtwig de bootstrap(App, [ConfigService]) toda su aplicación comparte una sola instancia.