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, el 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 app.component.ts.
Leí los documentos y tutoriales, nada funcionó.
Qué me estoy perdiendo ?
Gracias
RESUELTO
Mi problema era que estaba inyectando mi ConfigService dos veces. En el bootstrap 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 Grid... De esta forma, AppComponent y sus componentes secundarios compartirán la instancia del servicio.
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 comprender por qué necesita hacer eso, debe tener en cuenta la característica de "inyectores jerárquicos" de Angular2. Los siguientes enlaces podrían ser útiles:
Para la última versión de angular, si desea compartir el servicio, no puede agregarlo a la función de arranque. Simplemente agréguelo a la lista de proveedores de NgModule como lo haría con un servicio normal, su comportamiento predeterminado será singleton.
bootstrap (componente de la aplicación);
@NgModule({ declarations: [ .... ], imports: [ .... ], providers: [ ConfigService, ....No agregue ConfigService a los providers de su componente. Esto da como resultado nuevas instancias para cada componente. Agréguelo a los providers de un componente principal común. Si lo agrega a su componente raíz o bootstrap(App, [ConfigService]) toda su aplicación comparte una sola instancia.