2016-09-28 80 views
1

我正在開發Angular 2中的第一個項目,並且正在開發用戶認證和與之相關的功能。一切進展順利,迄今爲止,文檔/示例已經很好地發揮了作用。Angular 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文件,這是從一個認證服務,基本檢查localStorage的一個認證令牌是由一個Django的REST API,作爲我的後端認證獲得的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']); 
    } 
} 

終於,在情況下,它是使用,我crea身份驗證服務以管理用戶是否已登錄:

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; 
    } 
} 

當我登錄或註銷時,我的dillema進入。在我登錄之前,導航欄只顯示「註冊」和「登錄」鏈接。登錄後,我被重定向到「我的日誌」頁面,但導航欄的內容不會更新。導航欄中不存在提供「我的日誌」,「我的團隊」和「註銷」鏈接的「註冊」和「登錄」鏈接。註銷也存在同樣的問題。

我在當前的實施中走向了正確的方向嗎?如果沒有,是否有一個簡單的解決方案/ 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}}

//輸出「Logged in:[object Object]」' '

Logged in:{{loggedIn | async}}

//輸出「已登錄:」 – SamF

+0

Thanx bro - 它像一個魅力 –

+0

嗨,這段代碼片段爲我工作,但經過2至3次登錄和註銷 - 它給了我錯誤:未捕獲(在承諾):RangeError:超過最大調用堆棧大小 –

相關問題