2016-05-11 2 views
5

Я пытаюсь использовать RxJS BehaviorSubject, который содержит boolean, представляющий, подключен или не подключен или подключен пользователь к приложению.Проблема с RxJs Пользователь BehaviorSubject не уведомляется об изменении стоимости

Вот компонент, который присоединяется к новому значению BehaviorSubject т.е. true, когда проверка подлинности пользователя:

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; 
} 

Вот класс/сервис, содержащий 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); 
    } 
} 

Однако это не имеет ожидаемого поведения: кажется, что authenticated$ от сеансовой службы относится только к setPersonalInfo и isAuthenticated от NavbarComponent не уведомляется вообще, когда вызывается this.authenticated$.next(true).

ответ

7

Кажется, что у вас есть несколько экземпляров SessionService. например вы предоставили его более одного раза, а экземпляр, который вы называете signin, - это не тот экземпляр, который вы ввели в NavbarComponent.

Это зависит от вашего проекта, как вы предоставляете свои услуги. Обычно сеансовые службы являются одиночными.
Я рекомендую удалить providers: [SessionService], с NavbarComponent.

+0

Большое спасибо! Это действительно проблема ... – balteo

+0

Большое спасибо @Abdulrahman –

1

Я обычно обеспечивают SessionService в загрузчике (а не с providers: []), чтобы убедиться, что вы разделяете один глобальныйSessionService экземпляр на протяжении всего приложения.

bootstrap(AppComponent, 
      [SessionService]); 
+0

Мне нравится 'bootstrap()', а потому, что это делает более очевидным, что провайдеры должны быть глобальными, но согласно руководству по стилю, глобальные поставщики не должны быть добавлен в 'bootstrap()', а вместо этого к корневому компоненту. Для этого нет никаких технических причин. Они просто считают его более удобным. –

Смежные вопросы