2017-05-03 32 views
5

我有一個簡單的Angular.io應用程序。 (angular-cli/4.1.0)Angular.io/Angular 4.如何在觸發另一個組件視圖時刷新一個組件視圖

我有一個呈現用戶名的NavbarComponent。

第一次訪問應用程序時,我第一次沒有登錄,我的應用程序重定向到LoginComponent。我的NavBar也呈現,但沒有用戶名。成功登錄後,我被重定向到我的HomeComponent。

這是問題所在。我的NavBar不顯示用戶名。但如果我做了刷新/ Ctrl + R的用戶名呈現。

出了什麼問題?

app.component.html

<nav-bar></nav-bar> 
<router-outlet></router-outlet> 

navbar.compoment.ts

import { Component, OnInit } from '@angular/core'; 

@Component({ 
    selector: 'nav-bar', 
    templateUrl: './navbar.component.html', 
    styleUrls: ['./navbar.component.css'] 
}) 
export class NavbarComponent implements OnInit { 

    me; 

    ngOnInit() { 
    this.me = JSON.parse(localStorage.getItem('currentUser')); 
    } 
} 

login.component.ts

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

import { AlertService, AuthenticationService } from '../_services/index'; 

@Component({ 
    moduleId: module.id, 
    templateUrl: 'login.component.html' 
}) 

export class LoginComponent implements OnInit { 
    model: any = {}; 
    loading = false; 
    returnUrl: string; 

    constructor(
     private route: ActivatedRoute, 
     private router: Router, 
     private authenticationService: AuthenticationService, 
     private alertService: AlertService) { } 

    ngOnInit() { 
     // reset login status 
     this.authenticationService.logout(); 

     // get return url from route parameters or default to '/' 
     this.returnUrl = this.route.snapshot.queryParams['returnUrl'] || '/'; 
    } 

    login() { 
     this.loading = true; 
     this.authenticationService.login(this.model.email, this.model.password) 
      .subscribe(
       data => { 
        this.router.navigate([this.returnUrl]); 
       }, 
       error => { 
        this.alertService.error(error); 
        this.loading = false; 
        this.errorMsg = 'Bad username or password';console.error('An error occurred', error); 
       }); 
    } 
} 

回答

5

正如JusMalcolm所述,OnInit不會再運行。

但是,您可以使用Subject來告訴NavbarComponent從本地存儲中獲取數據。

在你NavBarComponent進口Subject並宣佈它:

import { Subject } from 'rxjs/Subject'; 

.... 

public static updateUserStatus: Subject<boolean> = new Subject(); 

然後在你的構造訂閱:

constructor(...) { 
    NavbarComponent.updateUserStatus.subscribe(res => { 
    this.me = JSON.parse(localStorage.getItem('currentUser')); 
    }) 
} 

而在你LoginComponent,導入NavbarComponent,當你已經成功登錄,只需在主題上撥打next()NavbarComponent即可訂閱。

.subscribe(
    data => { 
     NavbarComponent.updateUserStatus.next(true); // here! 
     this.router.navigate([this.returnUrl]); 
    }, 
    // more code here 

您也可以使用共享服務,告訴NavbarComponent重新執行用戶的檢索。更多關於Official Docs的共享服務。

+0

謝謝AJT_82和@JusMalcolm。我會在這裏嘗試您的建議,我認爲您提到的共享服務可能是「最佳實踐」方式。不過,我認爲沒有一個更實用的方法來做到這一點是令人遺憾的。您應該能夠調用一種區域刷新或app.module刷新來查看路線並重新加載路線中的所有組件。 – ChrisWorks

+1

感謝提供rxjs的人! –

0

由於部件已經被初始化, ngOnInit()在登錄後不運行。一種解決方案適用於喲你的情況是訂閱路由器參數,檢查用戶是否登錄。

例如。

this.route.queryParams 
     .map(params => params['loggedIn']) 
     .subscribe(loggedIn => { 
      if (loggedIn) { 
       this.me = JSON.parse(localStorage.getItem('currentUser')); 
      } 
     }); 
0

如果您可以在進行身份驗證時從後端返回名稱,則可以將AuthenticationService注入到NavbarComponent並在navbar.component.html中綁定所需的名稱。

NavbarComponent:

export class NavbarComponent { 
    ... 
    constructor(private authservice: AuthenticationService) {} 
    ... 
} 

navbar.component。html:

<span>Welcome {{authservice.name}}!</span> 
相關問題