Angular2-Compartir 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, 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 la cuadrícula.componente.ts, la línea _configService.getConfig() devuelve un objeto vacío, pero se llena justo antes en la aplicación.componente.ts.

Leí los documentos y tutoriales, nada funcionó.

¿Qué soy ¿desaparecido ?

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.

He eliminado el ajuste providers y su trabajo !

Author: Łukasz, 2016-02-08

3 answers

Usted lo define dentro de sus dos componentes. Así que 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 providers a su componente Grid... De esta manera, la instancia de servicio será compartida por AppComponent y sus componentes secundarios.

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

bootstrap(AppComponent, [ ConfigService ]);

Para entender por qué necesita hacer eso, debe estar al tanto de la característica de "inyectores jerárquicos" de Angular2. Los siguientes enlaces podrían ser útiles:

 26
Author: Thierry Templier,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:47:32

Para la última versión de angular, si desea compartir el servicio, no puede agregarlo a la función bootstrap. Simplemente agréguelo 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,
....
 5
Author: Mike D,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-10-18 21:53:23

No agregue ConfigService a providers de su componente. Esto da lugar a nuevas instancias para cada componente. Agrégalo a providers de un componente padre común. Si lo agrega a su componente raíz o bootstrap(App, [ConfigService]), toda su aplicación comparte una sola instancia.

 4
Author: Günter Zöchbauer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-02-08 15:23:27