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é !
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:
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,
....
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.