2016-05-11 3 views
5

Sto cercando di utilizzare un RxJS BehaviorSubject che contiene un boolean che rappresenta o meno un utente è connesso/connesso nell'applicazione.Problema con interlocutore di RxJs BehaviorSubject non essere informato della modifica del valore

Qui è il componente che aderisce al nuovo BehaviorSubject valore cioè true quando l'utente è autenticato:

import {Component, OnInit} from '@angular/core'; 
import {CollapseDirective} from 'ng2-bootstrap'; 
import {PublicNavbarComponent} from './public.navbar.component'; 
import {PrivateNavbarComponent} from './private.navbar.component'; 
import {SessionService} from '../../session/session.service'; 

@Component({ 
    selector: 'navbar', 
    templateUrl: 'app/shared/components/navbar.component.html', 
    providers: [SessionService], 
    directives: [PublicNavbarComponent, PrivateNavbarComponent, CollapseDirective] 
}) 
export class NavbarComponent implements OnInit { 

    constructor(private sessionService:SessionService) { 
    } 

    ngOnInit() { 
     this.sessionService.authenticated$.subscribe({ 
      next: (value)=> this.isAuthenticated = value 
     }); 
    } 

    isAuthenticated:boolean = false; 

    isCollapsed:boolean = true; 
} 

Ecco classe/servizio contenente la BehaviorSubject:

import {Injectable} from '@angular/core'; 
import {Http, Headers, RequestOptions} from '@angular/http'; 
import {Credentials} from '../shared/models/credentials.model'; 
import {BehaviorSubject} from 'rxjs/BehaviorSubject'; 
import 'rxjs/Rx'; 

@Injectable() 
export class SessionService { 

    authenticated$:BehaviorSubject<boolean> = new BehaviorSubject(false); 
    currentUserAccount; 

    constructor(private http:Http) { 
    } 

    signin(credentials:Credentials) { 
     let headers = new Headers({'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'}); 
     let options = new RequestOptions({headers: headers}); 
     this.http.post('/api/signin', 'username=' + credentials.username + '&password=' + credentials.password, options) 
      .subscribe(response=> 
       this.setPersonalInfo(response.headers.get('x-auth-token')) 
      ); 
    } 

    setPersonalInfo(sessionToken) { 
     localStorage.setItem('authenticated', 'true'); 
     localStorage.setItem('sessionToken', sessionToken); 
     this.authenticated$.next(true);//next() from false to true 
     this.http.get('/api/utils/current-useraccount') 
      .subscribe(param => this.currentUserAccount = param); 
    } 
} 

Tuttavia questo non ha il comportamento previsto: sembra che lo authenticated$ dal servizio di sessione sia vero solo entroLa funzionee isAuthenticated da NavbarComponent non viene notificata quando viene richiamato this.authenticated$.next(true).

risposta

7

Sembra che tu abbia più istanze di SessionService. per esempio. l'hai fornito più volte e l'istanza che chiami signin in non è la stessa istanza di quella che hai iniettato in NavbarComponent.

Dipende dal progetto in cui si forniscono i servizi. Solitamente i servizi di sessione sono singleton.
Mi raccomando di rimuovere providers: [SessionService], da NavbarComponent.

+0

Grazie mille! Questo è stato davvero il problema ... – balteo

+0

Grazie mille @Abdulrahman –

1

Io di solito fornisco SessionService a bootstrap (e non con providers: []) per essere sicuri di condividere quella globaleSessionService esempio per tutta l'intera applicazione.

bootstrap(AppComponent, 
      [SessionService]); 
+0

Mi piace 'bootstrap()' anche perché rende più ovvio che i provider dovrebbero essere globali ma secondo la guida di stile, i provider globali non dovrebbero essere aggiunto a 'bootstrap()' ma al componente root. Non ci sono ragioni tecniche per questo. Lo considerano solo più gestibile. –

Problemi correlati