2016-11-23 8 views
3

私はまだAngular 2の新機能を持っています。角2 - ルータのコンセントに読み込まれていないコンテンツ

私は非常にシンプルなアプリケーションを持っています。ログインページがあります。ログインに成功すると、ユーザーはサイドメニュー付きのページに移動します。ログイン画面にこのsidemenuはありません。ユーザーがログアウトすると、再びログインページに誘導されます。

ログイン後、サイドメニューは表示されますが、他のコンテンツは更新後にのみ表示されるという問題があります。ログアウトの場合と同じことですが、ログアウト後にページが空白になっている場合は、コンテンツをリフレッシュした後にのみ(ログインページ)が表示されます。私はおそらく何か間違っていますが、他の質問を見てもわかりません。ここで

は私のルーティングです:

import { NgModule } from '@angular/core'; 
import { RouterModule, Routes } from '@angular/router'; 

import { ProfileComponent } from './profile-component/profile-component.component' 
import { PageNotFoundComponent } from './page-not-found/page-not-found.component'; 
import { LoginComponent } from './login/login.component'; 
import { LoggedInGuard } from './logged-in/logged-in.guard'; 

const appRoutes: Routes = [ 
    {path: 'profile', component: ProfileComponent, canActivate: [LoggedInGuard]}, 
    {path: 'login', component: LoginComponent}, 
    {path: '', component: LoginComponent}, 
    {path: '**', component: PageNotFoundComponent}, 
]; 

@NgModule({ 
    imports: [ 
    RouterModule.forRoot(appRoutes) 
    ], 
    exports: [ 
    RouterModule 
    ] 
}) 
export class AppRoutingModule { 
} 

LoginComponent

import {Component, OnInit} from '@angular/core'; 
import {FormBuilder, FormGroup, Validators} from '@angular/forms'; 
import {LoginService} from '../login-service/login-service.service'; 
import {Router} from '@angular/router'; 


@Component({ 
    selector: 'app-login', 
    templateUrl: './login.component.html', 
    styleUrls: ['./login.component.scss'], 
    providers: [ LoginService ] 
}) 
export class LoginComponent implements OnInit { 

    loginForm: FormGroup; 
    error: String; 

    constructor(private formBuilder: FormBuilder, 
       private loginService: LoginService, 
       private router: Router) { 
    } 


    ngOnInit() { 
    if (this.loginService.isLoggedIn()) { 
     this.router.navigate(['/profile']); 
    } 
    this.loginForm = this.formBuilder.group({ 
     username: ['', Validators.required], 
     password: ['', Validators.required] 
    }); 
    } 

    login(): void { 
    let self = this; 
    this.loginService.login(this.loginForm.value.username, this.loginForm.value.password).subscribe(function (result) { 
     if (result) { 
     self.router.navigate(['/profile']); 
     } 

    }, function (error) { 
     self.error = 'Invalid'; 
    }); 
    } 
} 

AppComponent HTMLは次のようになります。

<md-toolbar color="primary" *ngIf="isLoggedIn()"> 
    <span>Sporter volgsysteem</span> 
</md-toolbar> 

<md-sidenav-layout *ngIf="isLoggedIn()"> 
    <md-sidenav #start mode="side" [opened]="true"> 
     <a routerLink="/add" routerLinkActive="active" md-button color="primary" disabled="false"><md-icon class="icon">add</md-icon><span class="nav-item">Toevoegen</span></a> 
     <a routerLink="/compare" routerLinkActive="active" md-button color="primary"><md-icon class="icon">swap_horiz</md-icon><span class="nav-item">Vergelijken</span></a> 
     <a routerLink="/search" routerLinkActive="active" md-button color="primary"><md-icon class="icon">search</md-icon><span class="nav-item">Zoeken</span></a> 
     <a routerLink="/profile" routerLinkActive="active" md-button color="primary"><md-icon class="icon">account_box</md-icon><span class="nav-item">Profiel</span></a> 
     <a routerLink="/feedback" routerLinkActive="active" md-button color="primary"><md-icon class="icon">feedback</md-icon><span class="nav-item">Feedback</span></a> 
     <a routerLink="/faq" routerLinkActive="active" md-button color="primary"><md-icon class="icon">info</md-icon><span class="nav-item">FAQ</span></a> 

     <div class="spacer"></div> 

     <a md-button color="primary" routerLink="/login" (click)="logout()"><md-icon class="icon">exit_to_app</md-icon><span class="nav-item">Uitloggen</span></a> 
    </md-sidenav> 


    <router-outlet></router-outlet> 
</md-sidenav-layout> 


<router-outlet *ngIf="!isLoggedIn()"></router-outlet> 

AppComponent

import {Component} from '@angular/core'; 
import {LoginService} from "./login-service/login-service.service"; 
import {Router } from '@angular/router' 


@Component({ 
    selector: 'app-root', 
    templateUrl: './app.component.html', 
    styleUrls: ['./app.component.scss'], 
    providers: [] 
}) 
export class AppComponent { 

    constructor(private loginService : LoginService, 
       private router: Router) { 
    } 

    logout() { 
    this.loginService.logout(); 
    this.router.navigate(['/login']); 
    } 

    isLoggedIn() { 
    return this.loginService.isLoggedIn(); 
    } 

} 

ログイン後にProfileComponentの内容が表示されないのはなぜですか。ログアウト後にログインページが表示されないのはなぜですか?

更新

大半は、それはので、私は店の1を削除したことを確認し、sidemenuレイアウトのすべての時間を表示するため、複数の無名のrouter-outlet sであることが示唆されました。もちろん、テスト目的のために。それは問題を解決しません、それは私に同じ動作を与える:プロファイルの内容は、更新後にのみ読み込まれます。

アップデート2 私はこれは、私は上記のコメントが示唆するような問題は、二重ルータ・アウトレットであると考えていrouter-outlet

+0

'AppComponent'は2つの' 'を持ち、どちらも 'name =" xxx "'を持っていません。ルートごとに名前の付いていないルータコンセントは1つだけ許可されます。 –

+0

@GünterZöchbauer '* ngIf'のために1つしか表示されませんが?私はコンソールにエラーは表示されません。 –

+0

ああ、申し訳ありませんが、私は最初の '* ngIf'を見逃しました。 –

答えて

3

@bhetzieと@ハイメ・トレスと私はさらに調査し、私自身の仮説から上記のコメントに続いて。 問題は実際にはダブルrouter-outletであることが判明しました。

解決方法は、LoginModuleモジュールを抽出し、そのモジュールでログインページにリダイレクトすることでした。それ以外の場合は、SvsModuleと呼ばれる別のモジュールにルーティングします。これはサイドナビゲーション構造でログインしたコンテンツを表示します。

だからSvsModuleは、次のルーティングがあります。

RouterModule.forChild([ 
    {path: 'svs', component: ProfileComponent, canActivate:[LoggedInGuard]}, 
    {path: 'svs/profile', component: ProfileComponent, canActivate:[LoggedInGuard]} 
]) 

をそしてProfileComponentは、次のHTMLを使用しています:

<md-sidenav-layout> 
    <md-sidenav #start mode="side" [opened]="true"> 
    <md-nav-list> 
     <a routerLink="/add" routerLinkActive="active" md-button color="primary" disabled="false"> 
     <md-icon class="icon">add</md-icon> 
     <span class="nav-item">Toevoegen</span> 
     </a> 
     <a routerLink="/compare" routerLinkActive="active" md-button color="primary"> 
     <md-icon class="icon">swap_horiz</md-icon> 
     <span class="nav-item">Vergelijken</span> 
     </a> 
     <a routerLink="/search" routerLinkActive="active" md-button color="primary"> 
     <md-icon class="icon">search</md-icon> 
     <span class="nav-item">Zoeken</span> 
     </a> 
     <a routerLink="/profile" routerLinkActive="active" md-button color="primary"> 
     <md-icon class="icon">account_box</md-icon> 
     <span class="nav-item">Profiel</span> 
     </a> 
     <a routerLink="/feedback" routerLinkActive="active" md-button color="primary"> 
     <md-icon class="icon">feedback</md-icon> 
     <span class="nav-item">Feedback</span> 
     </a> 
     <a routerLink="/faq" routerLinkActive="active" md-button color="primary"> 
     <md-icon class="icon">info</md-icon> 
     <span class="nav-item">FAQ</span> 
     </a> 

     <div class="spacer"></div> 

     <a md-button color="primary" routerLink="/login" (click)="logout()"> 
     <md-icon class="icon">exit_to_app</md-icon> 
     <span class="nav-item">Uitloggen</span></a> 
    </md-nav-list> 

    </md-sidenav> 
    <router-outlet></router-outlet> 

</md-sidenav-layout> 
私は答えとしてこれを受け入れますが、前述のユーザーのおかげで私を助けるために

私の道に

2

を表示する*ngIfを使用することに関連している推測しています。私は私のプロジェクトでこのようなことをしました。

これが私の解決策だった:

私は、最初のログインの状態を判断するためのサービスを(私は行動の対象にこれを変更することに取り組んでいます、そのイベントのエミッタは良い習慣ではありません実現)を作成

GlobalEventsManager

import { EventEmitter, Injectable } from '@angular/core'; 


@Injectable() 
export class GlobalEventsManager { 
    public showNavBar: EventEmitter<boolean> = new EventEmitter<boolean>(); 



} 

私は、ログイントークンの有効期限が切れていないかどうかを確認する私のルートのauthguardを使用しました。私のログイン・コンポーネントを使用して、ユーザーがログインには、私は本当の

ログインしGlobalEventsManagerを設定すると、私はこの

AuthGuard

import { Injectable } from '@angular/core'; 
import { Router, CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router'; 
import { tokenNotExpired } from 'angular2-jwt'; 
import { GlobalEventsManager } from './GlobalEventsManager'; 


    @Injectable() 
    export class AuthGuard implements CanActivate { 

     constructor(private router: Router, private globaleventsManager: GlobalEventsManager) {} 
     canActivate(next: ActivatedRouteSnapshot, 
        state: RouterStateSnapshot) { 

     if (tokenNotExpired('currentUser')) { 
      this.globaleventsManager.showNavBar.emit(true); 
      return true; 

     } else { 
      localStorage.removeItem('currentUser'); 
      this.router.navigate(['/login']); 
      return false; 
     } 

     } 


    } 

ためangular2-JWTライブラリを使用

constructor(
     private router: Router, 
     private authenticationService: AuthenticationService, 
     private globaleventsManager: GlobalEventsManager) { } 

ngOnInit() { 
     // reset login status 

     this.authenticationService.logout(); 
     this.globaleventsManager.showNavBar.emit(false); 
    } 

    login() { 
     this.loading = true; 
     this.authenticationService.login(this.model.username, this.model.password) 
      .subscribe((result) => { 
       this.globaleventsManager.showNavBar.emit(true); 
       this.router.navigate(['/']); 

私のnavbarでは、私はGlobalEventsManagerを購読して、結果をブール型プロパティ:

ナビゲーションバー

import { Component } from '@angular/core'; 
import { Router } from '@angular/router'; 
import { NavActiveService } from '../../../services/navactive.service'; 
import { GlobalEventsManager } from '../../../services/GlobalEventsManager'; 

@Component({ 
    moduleId: module.id, 
    selector: 'my-navbar', 
    templateUrl: 'navbar.component.html', 
    styleUrls:['navbar.component.css'], 
}) 
export class NavComponent { 
    showNavBar: boolean = true; 

    constructor(private router: Router,    
       private globalEventsManager: GlobalEventsManager){ 

    this.globalEventsManager.showNavBar.subscribe((mode:boolean)=>{ 
     this.showNavBar = mode; 
    }); 

    } 

} 

私のナビゲーションバーのHTMLでは、私は今、2 navbarsを作成することができ、1つのナビゲーションバーは、単純にログインNAVを持っており、私のauthguard通知はtoeknは有効期限が切れていることとき、またはユーザーがログインしていない場合は、オプションとしてログインだけでナビゲーションバーが表示されます。一度、GlobalEventsManager値の変化をログインし、自分のナビゲーションバーにログインして表示されます。

ナビゲーションバーHTML

<div *ngIf="showNavBar"> 
//My logged in navbar 
</div> 
<div *ngIf="!showNavBar"> 
//navbar that just displays login as an option 
</div> 
+0

div-insideの中に 'router-outlet'を入れると、これはうまくいくのですか?私はこれを試しましたが、問題は '* ngIf'によってダイジェストがすでに行われていることが原因で発生したと考えられ、次に' router-outlet'がDOMに追加されます。それとも、そういうものなんだろうと思っています。少なくとも –

+0

ルータのアウトレットは1つだけにしてください。私はあなたが提案したようにそれが問題だと思う – Bhetzie

0

移動呼び出しをngZoneに入れてください。 (Angular 5)

import { NgZone } from "@angular/core"; 
import { Router } from "@angular/router"; 

constructor(
    private ngZone: NgZone, 
    private router: Router 
) {} 

... 

this.ngZone.run(() => { 
    this.router.navigate(['/profile']); 
}); 
関連する問題