2016-06-16 17 views
3

Navbarアイテムを使用できないようにするために、ユーザーがNavbarコンポーネントにログインしているかどうかを取得しようとしています。私はBehaviorSubjectを使ってデータをマルチキャストしています。次のコードで見ることができるように私のAuthenticationServiceはBehaviorSubjectオブジェクトを保持している次のようにコードが見えトリガーBehaviorSubject.nextが呼び出されたときにObservable.subscribeメソッドが起動しない

import {Injectable} from '@angular/core'; 
import {Http, RequestOptions, Headers} from '@angular/http'; 
import {LocalStorage, SessionStorage} from "angular2-localstorage/WebStorage"; 
import {BehaviorSubject} from 'rxjs/BehaviorSubject'; 

import {Credentials} from './credentials'; 

@Injectable() 
export class AuthenticationService { 
    private _baseUrl="http://localhost:8080/webapi/authenticate/"; 
    private loggedIn: boolean; 
    // Observable UserLoggedIn source 
    private _userLoggedInBehavior = new BehaviorSubject<boolean>(false); 
    // Observable UserLoggedIn stream 
    userLoggedInBehaviorStream = this._userLoggedInBehavior.asObservable(); 

    constructor(private _http: Http){ 
     this.loggedIn = localStorage.getItem("authToken"); 
    } 

    authenticate(credentials: Credentials){ 
     return this._http.post(
          this._baseUrl 
          , JSON.stringify(credentials) 
          , this.getOptions() 
          ) 
        .map(res => res.json()) 
        .map((res) => { 
         if (res.success) { 
          sessionStorage.setItem("authToken", res.data.token); 
          this.loggedIn = true; 
         } 
         return res.success; 
        }); 
    } 

    logout() { 
     sessionStorage.removeItem("authToken"); 
     this.loggedIn = false; 
    } 

    isLoggedIn() { 
     return this.loggedIn; 
    } 

    changeUserLoggedInBehavior(loggedIn) { 
     this._userLoggedInBehavior.next(loggedIn); 
    } 

    // This was necessary because api accepts only JSON 
    // and if we do not put this header in requests API 
    // responds with 415 wrong media object. 
    getOptions(){ 
     var jsonHeader = new Headers({ 
      'Content-Type':'application/json' 
     }); 
     var options = new RequestOptions({ 
      headers: jsonHeader 
     }); 
     return options; 
    } 
} 

マイAuthenticationComponentコード:

import {Component, OnInit, EventEmitter} from '@angular/core'; 
import {CanDeactivate, Router} from '@angular/router-deprecated'; 
import {ControlGroup, Control, Validators, FormBuilder} from '@angular/common'; 

import {AuthenticationService} from './authentication.service'; 
import {Credentials} from './credentials'; 
import {EmailValidator} from '../../validators/email-validator'; 

@Component({ 
    selector:'auth' 
    , templateUrl:'app/components/authentication/authentication.component.html' 
    , providers:[AuthenticationService] 
}) 
export class AuthenticationComponent{ 
    form: ControlGroup; 
    title: string = "LogIn"; 
    credentials: Credentials = new Credentials(); 

    constructor(
     fb: FormBuilder 
     , private _authService: AuthenticationService 
     , private _router: Router){ 

     this.form = fb.group({ 
      emailId:[ 
       '' 
       , Validators.compose(
         [ 
          Validators.required 
          , EmailValidator.mustBeValidEmail 
         ] 
        ) 
       ] 
      ,password:[ 
       '' 
       , Validators.compose(
         [ 
          Validators.required 
         ] 
        ) 
      ] 
     }); 
    } 

    save(){ 
     this._authService.authenticate (this.credentials) 
       .subscribe((result) => { 
        if (result) { 
         this._authService.changeUserLoggedInBehavior(true); 
         this._router.navigate(['Home']); 
        } 
       }); 
    } 
} 

最後に、私のNavbarComponentを次のように:

import {Component, OnInit, OnDestroy} from '@angular/core'; 
import {RouterLink} from '@angular/router-deprecated'; 
import {Subscription} from 'rxjs/Subscription'; 

import {AuthenticationService} from '../components/authentication/authentication.service'; 

@Component({ 
    selector:'navbar' 
    , templateUrl: 'app/navbar/navbar.component.html' 
    , directives:[RouterLink] 
    , providers:[AuthenticationService] 
}) 
export class NavbarComponent implements OnInit, OnDestroy{ 
    private _isUserLoggedIn: boolean=false; 
    subscription: Subscription; 
    constructor(
     private _authService: AuthenticationService 
    ){} 

    ngOnInit(){ 
     this.subscription = this._authService.userLoggedInBehaviorStream 
           .subscribe(
            loggedIn => this._isUserLoggedIn = loggedIn 
            ); 
    } 

    ngOnDestroy(){ 
     // prevent memory leak when component is destroyed 
     this.subscription.unsubscribe(); 
    } 

    public setUserLoggedId (isLoggedIn: boolean){ 
     this._isUserLoggedIn = isLoggedIn; 
    } 
} 

私はコードを書くのにthis as an exampleを使用しました。私が間違っているところを教えてください。

答えて

5

問題は、あなたのコンポーネントの両方でプロバイダを指定しているということです。

providers:[AuthenticationService] 

たびコンポーネントにあなたはそれが新しいインスタンスを取得しますいくつかのサービスを提供しています。いくつかの親コンポーネントにAuthenticationServiceを提供し、子コンポーネントまたはブートレベルに注入するだけです。

+0

提案が有効でした。アプリケーションで複数回使用するため、AuthenticationServiceをブートレベルに追加しました。あなたの提案を詳述するドキュメントに私を指摘できますので、自分で教えることができます。 –

+1

私は、ここでこの部分で説明していると思う:https://angular.io/docs/ts/latest/guide/dependency-injection.html –

関連する問題