2

J'ai un simple composant progressBar afin d'afficher (ou non) la barre de progression. Et un service observable simple.Observable BehaviorSubject Service - Singleton et les fournisseurs

Voici le service:

import { Injectable } from '@angular/core'; 
import { Http } from '@angular/http'; 
import { Observable } from 'rxjs/Observable'; 
import { BehaviorSubject } from 'rxjs/BehaviorSubject'; 

@Injectable() 
export class ProgressBarService { 
    subject = new BehaviorSubject<any>(false); 
    changes = this.subject 
       .asObservable() 
       .do(changes => console.log('new state', changes)); 

    constructor(private http: Http) { 
    } 
    show() { 
    this.subject.next(true); 
    } 
    hide() { 
    this.subject.next(false); 
    } 
} 

Rien d'exceptionnel ici, juste un BehaviorSubject qui est réglé par défaut avec false, hide/show est utilisé pour changer la valeur avec .next().

Le composant ressemble à ceci:

import { Component, OnInit } from '@angular/core'; 
import { Observable } from 'rxjs/Observable'; 
import { ProgressBarService } from './progressbar.service'; 

@Component({ 
    selector: 'app-progressbar', 
    templateUrl: './progressbar.component.html', 
    styleUrls: ['./progressbar.component.scss'], 
    providers:[ProgressBarService] 
}) 

export class ProgressbarComponent implements OnInit { 

    isDisplay : boolean; 

    constructor(private $progressbar : ProgressBarService) { } 

    ngOnInit() { 
    this.$progressbar 
     .changes 
     .subscribe((display : boolean) => this.isDisplay = display); 
    } 

    showProgress(){ 
    (this.isDisplay) 
     ? this.$progressbar.hide() 
     : this.$progressbar.show(); 
    } 
} 

Au cours de l'initialisation, le composant abonnez-vous au sujet afin d'obtenir la valeur par défaut et réglez-le sur isDisplay. showProgress est seulement utilisé pour l'essayer dans mon modèle.

<md-progress-bar mode="indeterminate" color="accent" *ngIf="isDisplay"></md-progress-bar> 

<button type="submit" md-raised-button color="primary" (click)="showProgress()">Show/hide progressBar</button> 

Et cela fonctionne très bien lorsque le service est utilisé à l'intérieur du composant. Mais quand j'essaye d'appeler ce service à l'intérieur d'un autre composant, cela ne fonctionne pas.

Exemple: Mon autre composant appelé profilesComponent

import { ProgressBarService } from ../progressbar/progressbar.service'; 

@Component({ 
    selector: 'profiles', 
    templateUrl: 'profiles.component.html', 
    providers: [ProgressBarService] 
}) 

export class ProfilesComponent implements OnInit { 

    toto :boolean = false; 

    constructor(private $progressbar : ProgressBarService) {} 

    ngOnInit() {} 

    showProgress() { 
    if(this.toto) { 
     this.$progressbar.hide(); 
     this.toto = false; 
    } else { 
     this.$progressbar.show(); 
     this.toto = true; 
    } 
    } 
} 

Je pense qu'il est parce que les deux composants ne partage pas la même instance du service, mais je ne peux pas trouver un moyen de le faire. (Peut-être les fournisseurs dans @NgModule?)

+3

Oui, cela pourrait être une raison. déclarez-le dans NgModule et supprimez des deux composants. – micronyks

+1

Saint ****! Vous avez raison, c'est la raison. J'ai enlevé le 'ProgressBarService' des composants du fournisseur puis je l'ai ajouté à' app.module.js'. Maintenant, ils partagent tous deux la même instance et ça marche! Eh bien, merci monsieur. Je viens de comprendre une chose ce soir :) – ByJC

+0

Super !!! Profitez de Angular2 alors! – micronyks

Répondre

2

Grâce à @micronyks, voici la solution.

Pour chaque composant, j'ajoute le service dans le composant du fournisseur. En résultat, les composants créent une nouvelle instance du service.

Afin de résoudre le problème, j'ai retiré le service des fournisseurs de chaque composant puis le fournir au module principal. Les composants partagent maintenant la même instance et la barre de progression est bien affichée.