2016-11-09 103 views
2

這是我第一個使用Angular 2的項目/應用程序。我目前被困在應用程序的登錄問題中。所以,在我的web應用程序:Node/Angular 2:更新導航欄並在用戶登錄後顯示側欄

期望:

  1. 我加載登錄組件首次。在這種情況下,導航欄顯示「登錄」按鈕。

  2. 正確登錄後,我可以轉到儀表板組件。在儀表板組件中,我可以在左側看到側邊欄,我的導航欄更新爲顯示「註銷」按鈕。

  3. 當我點擊「退出」時,它應該優雅地簽約我。

對於一個更清晰的畫面,我已經上傳an album顯示的登錄和儀表板應該怎麼樣子,登錄後的實際發生。

現實:

  1. 我在currentUser鍵使用localStorage從角2至當前用戶存儲在密鑰currentUser並檢測用戶是否已登錄只要deoesn't值,則。登錄組件工作正常。否則,它會顯示一個沒有標題的空白儀表板。
  2. 登錄後,邊欄和更新的導航欄與登錄屏幕混雜在一起,而儀表板不顯示。

我製作了a temporary Git repo向您展示我的代碼。

如果您注意到,Angular前端連接到Node.js後端。 Node.js後端工作得很好。

我認爲主要的問題在於我使用Observable(告訴每個用戶登錄的訂閱組件),路由上的認證保護以及認證服務本身。

爲了滿足上面的期望,我試着使用Observables並將值發送到訂閱組件。然而,我上面提到的'現實'點發生了,而且我還沒有找到一種方法來解決它。

那麼,你能幫助告訴我問題在哪裏,我能做些什麼來解決它?非常感謝您的意見,謝謝。

回答

0

最後,我發現了這個問題。

認證後衛正在從this.authService.isLoggedInObservable()方法遞送Observable方法。它不會爲路線提供適當的值,以瞭解用戶是否實際登錄。

如果您在回購中看到,我使用Observable<boolean>來告知其他組件/路由是否已登錄。

我做的一個解決方法是在警衛內部實際存儲一個私有變量。我這樣做是爲了讓守衛裏面的canActivate()方法只返回那個私有變量:true意味着我已經登錄,false否則。

如何讓該私有變量知道我現在已登錄,並且其值需要更改?

在構造函數中,我確保警衛正在用該布爾值訂閱Observable,並相應地更新該變量。

我剛剛從AuthenticationGuard更改了代碼。沒有什麼比這更少的了。

import { Injectable } from "@angular/core"; 
import { Router, CanActivate } from "@angular/router"; 

import { Observable } from "rxjs"; 

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

@Injectable() 
export class AuthenticationGuard implements CanActivate { 

    private isLoggedIn: boolean; // to store the "logged in" state 

    constructor(
     private router: Router, 
     private authService: AuthenticationService) { 

     this.authService.isLoggedInObservable().subscribe((val) => { 
      this.isLoggedIn = val; // update as subscribed 
      // redirect to login page if not logged in yet 
      if (!val) this.router.navigate(["/login"]); 
     }); 
    } 

    canActivate() { // only returns that private variable 
     return this.isLoggedIn; 
    } 
}