Angular2-partage de données entre les composantes utilisant des services

j'ai un objet que je veux partager entre mes composants dans une application Angular2.

Voici la source du premier composant:

/* 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);
    }
}

et le deuxième élément:

/* 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();
    }
  }

et enfin mon petit service, le 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;
    }
}

Mes données ne sont pas partagées, dans la grille.composant.ts, la ligne _configService.getConfig() renvoie un objet vide, mais il est rempli juste avant dans App.composant.ts.

j'ai lu les docs et les tutoriels, rien n'a fonctionné.

Qu'est-ce que je rate ?

Merci

résolu

mon problème était que j'injectais mon ConfigService deux fois. Lors du lancement de l'application et dans le fichier où je l'utilise.

j'ai enlevé le providers et son réglage travaillé !

25
demandé sur Łukasz 2016-02-08 18:21:37

3 réponses

vous le définissez à l'intérieur de vos deux composants. Donc le service n'est pas partagé. Vous avez une instance pour le composant AppComponent et une autre pour le composant Grid .

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

la solution rapide est de supprimer l'attribut providers de votre composant de grille... De cette façon, l'instance de service sera partagée par les composants AppComponent et ses enfants.

L'autre solution est d'enregistrer le fournisseur correspondant dans la fonction bootstrap . Dans ce cas, l'instance sera partagé par l'ensemble de l'application.

bootstrap(AppComponent, [ ConfigService ]);

pour comprendre pourquoi vous devez faire cela, vous devez être conscient de la caractéristique" injecteurs hiérarchiques " de Angular2. Les liens suivants pourraient être utiles:

26
répondu Thierry Templier 2017-05-23 11:47:32

pour la dernière version d'angular, si vous voulez partager le service, vous ne pouvez pas l'ajouter à la fonction bootstrap. Il suffit de l'ajouter à la liste des fournisseurs de NgModule comme vous le feriez avec un service normal, son comportement par défaut sera singleton.

bootstrap (AppComponent);

@NgModule({
    declarations: [
        ....
    ],
    imports: [
       ....     
    ],
    providers: [
        ConfigService,
....
5
répondu Mike D 2016-10-18 21:53:23

n'ajoutez pas ConfigService à providers de votre composant. Il en résulte de nouvelles instances pour chaque composant. Ajoutez-le à providers d'un composant parent commun. Si vous l'ajoutez à votre composant root ou bootstrap(App, [ConfigService]) , votre application entière partage une seule instance.

4
répondu Günter Zöchbauer 2016-02-08 15:23:27