2016-05-11 21 views
5

ユーザがアプリケーションに接続/ログインしているかどうかを表すbooleanを含むRxJS BehaviorSubjectを使用しようとしています。しかしRxJsの問題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); 
    } 
} 

:ここ

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次のとおりです。ここで

は、ユーザーが認証したとき trueすなわち新しい BehaviorSubject値にサブスクライブするコンポーネントですこれは予期された動作をしていません。 authenticated$がセッションサービスからのものであることはが呼び出された場合、関数と isAuthenticatedから NavbarComponentはまったく通知されません。

答えて

7

SessionServiceの複数のインスタンスがあるようです。例えば複数回提供しましたが、signinと入力したインスタンスは、NavbarComponentに注入したインスタンスと同じインスタンスではありません。

あなたのサービスをどのように提供するかは、プロジェクトデザインによって異なります。通常、セッションサービスはシングルトンです。
からproviders: [SessionService],を削除することをおすすめします。

+0

ありがとうございます!それは確かに問題でした... – balteo

+0

ありがとう@Abdulrahman –

1

私は通常、あなたが全体のアプリを通じて一つのグローバルSessionServiceインスタンスを共有を確認する(providers: []としていない)、ブートストラップでSessionServiceを提供しています。

bootstrap(AppComponent, 
      [SessionService]); 
+0

私は 'bootstrap()'も好きです。なぜなら、プロバイダがグローバルになっているはずですが、スタイルガイドによれば、グローバルプロバイダは'bootstrap()'に追加されますが、代わりにルートコンポーネントに追加されます。これには技術的な理由はありません。彼らはそれをより保守性があると考えているだけです。 –

関連する問題