RxJs的问题BehaviorSubject的订户未收到有关价值变化的通知

时间:2016-05-11 00:02:27

标签: typescript angular rxjs5

我正在尝试使用包含BehaviorSubject的RxJS boolean来表示用户是否在应用程序中连接/登录。

以下是用户经过身份验证后订阅新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的{​​{1}}未通知所有在调用NavbarComponent时。

2 个答案:

答案 0 :(得分:7)

好像你有SessionService的多个实例。例如您提供了多次,而您调用signin的实例与您在NavbarComponent中注入的实例不同。

这取决于您的项目设计如何提供服务。通常会话服务是单身人士 我建议从providers: [SessionService],删除NavbarComponent

答案 1 :(得分:1)

我通常会在引导程序中提供SessionService(而不是providers: [])以确保您在整个应用程序中共享一个全局 SessionService实例。

bootstrap(AppComponent,
            [SessionService]);