typescript - RxJs BehaviorSubject 的订阅者未收到值更改通知的问题

标签 typescript angular rxjs5

我正在尝试使用一个 RxJS BehaviorSubject,它包含一个 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);
    }
}

然而,这并没有预期的行为:似乎来自 session 服务的 authenticated$ 仅在 setPersonalInfo 函数和 isAuthenticated 中为真NavbarComponent 在调用 this.authenticated$.next(true) 时根本不会收到通知。

最佳答案

您似乎有多个 SessionService 实例。例如您不止一次提供了它,并且您在 signin 中调用的实例与您在 NavbarComponent 中注入(inject)的实例不同。

如何提供服务取决于您的项目设计。通常session服务都是单例的。
我建议从 NavbarComponent 中删除 providers: [SessionService],

关于typescript - RxJs BehaviorSubject 的订阅者未收到值更改通知的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37150891/

相关文章:

javascript - 如何在 Angular2 中停止 observable.timer

typescript - typescript d.ts 文件中的枚举

reactjs - 在函数上使用 React FC

angular - 有条件地将 RouterLink 或其他属性指令添加到 Angular 2 中的元素

javascript - 如何在 Angular 2 中的 Google map 上显示标记?

angular - 配置 Observable 以在推送新值时将所有先前值作为数组返回?

javascript - "OuterSubscriber is not defined"使用 rollup.js 打包时

angular - 让 moment.js 远离我的 Angular 构建输出

JavaScript 在推送到数组后停止循环执行

Angular 2 block 范围变量问题