Angular 7 Guard重定向仅在双击时有效

时间:2019-04-11 08:04:25

标签: javascript angular firebase local-storage

问题是我已经实现了Guard,旨在与特定目录配合使用。如果当前用户名的角色等于2,则应返回true。如果没有,则不应重定向。

这是我的app-routing-module.ts文件,问题在“用户列表”路径中,如果我们实现了[RoleGuard] canActivate

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

import { PokemonListComponent } from '../../src/app/pokemon-list/pokemon-list.component';
import {LoginComponent} from '../../src/app/login/login.component'
import { AuthGuard } from './auth.guard';
import { RoleGuard} from './role.guard'

import {UserListComponent} from './pokemon-list/user-list/user-list.component'


const routes: Routes = [
  {path: 'pokemonlist', component: PokemonListComponent , canActivate: [AuthGuard]},
  {path: 'login', component: LoginComponent},
  {path: '',redirectTo: '/login',pathMatch: 'full'},
  {path: 'userlist', component: UserListComponent , canActivate : [ RoleGuard]} //this is the guard we are looking at
]

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

这是我目前的角色。guard.ts

     import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree } from '@angular/router';
import { AngularFirestore, AngularFirestoreCollection } from '@angular/fire/firestore';
import { Router } from '@angular/router';
@Injectable({
  providedIn: 'root'
})
export class RoleGuard implements CanActivate {
  data2 //variable to store the role of the current user , (1 or 2) . If its 2 the canActivate should return true.

  constructor(public db: AngularFirestore, private myRoute: Router) {
    //role extraction 
    //We get the role by comparing the uid , and store it in the "data2" var
    var docRef = this.db.collection('users').doc(localStorage.getItem('user'));

    docRef.get().toPromise().then(doc => {
      if (doc.exists) {
        this.data2 = doc.data().role;
      }
    });


  }

  canActivate() {
    //if data2 is 2, means that the redirection should work
    if ( localStorage.getItem('user') && this.data2 == 2 ) {  
        return true;
    } else {
      return false;
    }


  }

}

发生点击的我的navbard组件,onUsersClick函数

        import { Component, OnInit, Output, EventEmitter } from '@angular/core';
import { AngularFireAuth } from '@angular/fire/auth';
import { AngularFirestore, AngularFirestoreCollection } from '@angular/fire/firestore';
import { Router } from '@angular/router';
import {AuthService} from '../services/auth.service'
@Component({
  selector: 'app-navbar',
  templateUrl: './navbar.component.html',
  styleUrls: ['./navbar.component.css']
})
export class NavbarComponent implements OnInit {
  @Output() featureSelected = new EventEmitter<string>();

  myName;

  fullUser: any;
  name: string;
  constructor(public firebase: AngularFireAuth, public db: AngularFirestore, public router: Router,  private _authS: AuthService) {
    let userID = localStorage.getItem('user')
    this.myName= localStorage.getItem('displayName');

    //retrieve logged user data

    let docRef = db.collection('users').doc(userID);


    docRef.get().toPromise().then(doc => {
      if (doc.exists) {
        this.fullUser = doc.data();
      } else {
        console.log("No such document!");
      }
    }).catch(function (error) {
      console.log("Error getting document:", error);
    });



  }

  ngOnInit() {
  }

  onUsersClick() {
    this.router.navigate(['/userlist']);
  }

  onPokemonClick(feature: string) {
    this.router.navigate(['/pokemonlist']);
  }

  onSignOut() {
    localStorage.clear();
  }



}

我的导航栏html

    <!--navbar-->
<nav class="navbar navbar-expand-lg navbar-dark">
  <a class="navbar-brand" href="#">Pokedex</a>
  <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent"
    aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
    <span class="navbar-toggler-icon"></span>
  </button>

  <div class="collapse navbar-collapse" id="navbarSupportedContent">
    <ul class="navbar-nav mr-auto">

      <li class="nav-item active">
        <a class="nav-link" (click)="onPokemonClick()">Pokemons <span class="sr-only">(current)</span></a>
      </li>
      <li class="nav-item active">
        <a class="nav-link" *ngIf="fullUser.role == 2" (click)="onUsersClick()">Users <span
            class="sr-only">(current)</span></a>
      </li>
      <li class="nav-item active">
        <a class="nav-link" (click)="onSignOut()"href="#">Sign Out <span class="sr-only">(current)</span></a>
      </li>
      <li class="nav-item active" *ngIf="myName != 'null'">
          <a class="nav-link" [ngStyle]="{'color': 'yellow'}">Welcome {{ myName }} !! <span class="sr-only">(current)</span></a>
      </li>



    </ul>

  </div>
</nav>

1 个答案:

答案 0 :(得分:1)

尝试:

@Injectable({
  providedIn: 'root'
})
export class RoleGuard implements CanActivate {
  constructor(public db: AngularFirestore) {
  }

   async canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<boolean>  {
    if (localStorage.getItem('user') ) {  
       const doc = await this.db.collection('users')
                 .doc(localStorage.getItem('user'))
                 .get()
                 .toPromise();
       return doc.exists && doc.data().role === 2 ? true : false;
    } else {
      return false;
    }
  }
}

该问题可能与以下事实有关:您在构造函数中解析了一个Promise,并期望在调用canActivate时可以得到结果。