首页 > 解决方案 > Angular 7 Guard 重定向仅适用于双击

问题描述

问题是我已经实现了一个 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;
    }


  }

}

我发生点击的导航栏组件,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>

标签: javascriptangularfirebaselocal-storage

解决方案


尝试:

@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;
    }
  }
}

canActivate该问题可能与您在构造函数中解析承诺并期望结果在调用时可用的事实有关。


推荐阅读