2016-09-28 5 views
1

私はAngular 2の私の最初のプロジェクトに取り組んでおり、ユーザー認証とそれに関連する機能について取り組んでいます。すべてが順調に進んでおり、ドキュメンテーション/サンプルがこれまで私に非常に役立っています。角度2 - ユーザーがログインしたときにナビゲーションバーの特定の要素のみを表示します

現在、ユーザーがログインしているときには自分のサイトのナビゲーションバーに特定のリンクのみを表示する機能を実装しようとしていますが、現在の実装は意図したとおりに動作しません。ナビゲーションバー内のリンクは、ページがリロードされたときにのみ変更され、認証されたユーザーが存在する/見つからない場合にのみ変更されます。 次は私の現在の実装である:ここでは

は、それが私のサイトのための「基本テンプレート」として使用され、私のapp.component.htmlファイルです:

<nav class="navbar navbar-default navbar-fixed-top"> 
    <div class="container-fluid"> 
    <div class="navbar-header"> 
     <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar"> 
     <span class="sr-only">Toggle navigation</span> 
     <span class="icon-bar"></span> 
     <span class="icon-bar"></span> 
     <span class="icon-bar"></span> 
     </button> 
     <a class="navbar-brand" href="">Project Name</a> 
    </div> 
    <div id="navbar" class="navbar-collapse collapse"> 
     <ul class="nav navbar-nav"> 
     <li><a *ngIf="loggedIn" routerLink="my-log">My Log</a></li> 
     <li><a *ngIf="loggedIn">My Team</a></li> 
     </ul> 
     <ul class="nav navbar-nav navbar-right"> 
     <li><a *ngIf="loggedIn" (click)="logout()">Logout</a></li> 
     <li><a *ngIf="!loggedIn" routerLink="register">Sign Up</a></li> 
     <li><a *ngIf="!loggedIn" routerLink="login">Login</a></li> 
     </ul> 
    </div> 
    </div> 
</nav> 
<router-outlet></router-outlet> 

と私のapp.component.tsファイル、基本的には、認証のために私のバックエンドとして機能しますジャンゴのREST APIからである認証トークンのためのlocalStorageをチェックする認証サービスからLOGGEDINを取得している:

import { Component } from '@angular/core'; 
import { Router } from '@angular/router'; 

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


@Component({ 
    selector: 'app-root', 
    templateUrl: './app.component.html', 
    styleUrls: ['./app.component.css'] 
}) 
export class AppComponent { 
    loggedIn = false; 

    constructor(private auth: AuthenticationService, private router: Router) { 
    this.loggedIn = this.auth.isLoggedIn(); 
    } 

    logout() { 
    localStorage.removeItem('authToken'); 
    this.router.navigate(['/login']); 
    } 
} 

、最終的には、ケースには、それは使用のものであり、私が使っている認証サービスユーザーがログインしているかどうかを管理するために使用します。

import { Injectable } from '@angular/core'; 
import { Http, Headers, RequestOptions, Response } from '@angular/http'; 

import { Observable } from 'rxjs/Rx'; 
import 'rxjs/add/operator/map'; 


@Injectable() 
export class AuthenticationService { 
    private baseApiUrl = 'http://localhost:8000/api/'; 
    private loggedIn = false; 

    constructor(private http: Http) { 
     this.loggedIn = !!localStorage.getItem('authToken'); 
    } 

    private extractData(res: Response) { 
     let body = res.json(); 
     return body; 
    } 

    userLogin(username: string, password: string) { 
     let url = this.baseApiUrl + 'login/'; 
     let body = JSON.stringify({'username': username, 'password': password}); 
     let headers = new Headers({'Content-Type': 'application/json'}); 
     let options = new RequestOptions({ headers: headers }); 

     return this.http.post(url, body, options).map(this.extractData); 
    } 

    isLoggedIn() { 
     return this.loggedIn; 
    } 
} 

私がログインまたはログアウトすると、私のディレマが来ます。ログインする前に、ナビゲーションバーには「登録」リンクと「ログイン」リンクのみが表示されます。ログイン後、「My Log」ページにリダイレクトされますが、Navbarの内容は更新されません。 「My Log」、「My Team」、および「Logout」へのリンクを提供する代わりに、「Register」と「Login」のリンクは引き続きナビゲーションバーに表示されます。同じ問題がログアウトにも存在します。

私は現在の実装で正しい方向に向かっていますか?そうでない場合は、私が記述した機能を実装するのに役立つAngular 2の簡単なソリューション/何かがありますか?

答えて

5

あなたは

import { Injectable } from '@angular/core'; 
import { Http, Headers, RequestOptions, Response } from '@angular/http'; 

import { Observable } from 'rxjs/Rx'; 
import { Subject } from 'rxjs/Subject'; 
import 'rxjs/add/operator/map';  

@Injectable() 
export class AuthenticationService { 
    private baseApiUrl = 'http://localhost:8000/api/'; 
    // change loggedIn to a subject 
    private loggedIn: Subject<boolean> = new Subject<boolean>(); 

    // make isLoggedIn public readonly 
    get isLoggedIn() { 
     return this.loggedIn.asObservable(); 
    } 
    constructor(private http: Http) { 
     this.loggedIn.next(!!localStorage.getItem('authToken')); 
    } 

    private extractData(res: Response) { 
     let body = res.json(); 
     return body; 
    } 

    userLogin(username: string, password: string) { 
     let url = this.baseApiUrl + 'login/'; 
     let body = JSON.stringify({'username': username, 'password': password}); 
     let headers = new Headers({'Content-Type': 'application/json'}); 
     let options = new RequestOptions({ headers: headers }); 

     return this.http.post(url, body, options).map(this.extractData); 

     // set this.loggedIn.next inside this.extractData method 
    }  
} 
以下のコンポーネントの使用において

loggedIn: any; 

constructor(private auth: AuthenticationService, private router: Router) { 
    this.loggedIn = this.auth.isLoggedIn; 
    } 

とテンプレートバインディングでasync pipeを使用し、以下のようにコードを更新することができます。

これが役立ちますように!

+0

サンプルコードをありがとう - 私はそれを実行する問題に実行しています。 テンプレートのloggedInプロパティにアクセスしようとすると、私は非同期パイプを使用しないと[オブジェクトオブジェクト]を取得し、非同期パイプを使用する場合は何も取得しません。 '

ログイン:{{loggedIn}}

//「ログインしました:[オブジェクトオブジェクト]」「 」

ログイン:{{loggedIn |このコードスニペットは私のために働いていましたが、ログインとログアウトの2〜3回後にエラーが発生しました:Uncaught(in asynchronous)}

//出力 "ログイン": – SamF

+0

Thanx bro - それは魅力的でした –

+0

promise):RangeError:最大呼び出しスタックサイズを超えました –

関連する問題