2016-09-28 82 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:超过最大调用堆栈大小 –

相关问题