Angular 2 -Route Guard无法在浏览器刷新上工作



在app.module.ts

中定义了这些路由
...
{ path: 'mypath', component: MyComponent, canActivate: [RouteGuard] }, 
{ path: '', redirectTo: '/home', pathMatch: 'full' },
{ path: '**', redirectTo: '/home'}

和此防护服务

import { Injectable } from '@angular/core';
import { CanActivate } from '@angular/router';
import { AngularFire } from 'angularfire2';
import { AngularFireAuth } from 'angularfire2';
@Injectable()
export class RouteGuard implements CanActivate {
  private loggedIn: boolean;
  constructor ( private af: AngularFire, private auth: AngularFireAuth ) {}
  canActivate(): boolean {
    this.auth.subscribe(auth => {
      if  (auth)  { this.loggedIn = true; }
      else        { this.loggedIn = false; }
//          this.router.navigate(['/login']); for future implememtation
       });
    return this.loggedIn;
  }
}

从URL //mysite/mypath刷新浏览器该应用程序转到 //mysite代替//mysite/mypath(还跳过默认值 路线)。

没有在我的路线上激活任何守卫(即: { path: 'mypath', component: MyComponent }一切正常。

有人知道这是否是角度错误?我如何避免这种行为?

我的开发设备是:

@angular/cli: 1.0.0-rc.1
node: 7.5.0
os: linux x64
@angular/cli: 1.0.0-rc.1
@angular/common: 2.4.9
@angular/compiler: 2.4.9
@angular/compiler-cli: 2.4.9
@angular/core: 2.4.9
@angular/flex-layout: 2.0.0-rc.1
@angular/forms: 2.4.9
@angular/http: 2.4.9
@angular/material: 2.0.0-beta.2
@angular/platform-browser: 2.4.9
@angular/platform-browser-dynamic: 2.4.9
@angular/router: 3.4.9

感谢您的帮助。

ps:我试图在堆栈溢出或GitHub问题上找到一个答案,而没有找到答案。我看到了一个类似的问题Angular 2路由在与Apache的页面刷新上不起作用,但这不是我的情况。

您可以对路线守卫产生异步结果:

 canActivate(): Promise<boolean> {
   let self = this;
    return this.auth.toPromise().then(auth => {
         if  (auth)  { self.loggedIn = true; }
         else { self.loggedIn = false; }
         self.router.navigate(['/login']); for future implememtation
        return self.loggedIn;
    });

}

感谢@bougarfaoui el Houcine和Younesm的建议,这是我的新警卫服务(完全取自这篇文章:创建一个使用Firebase

创建完整的Angular ageletication System

它可以完美地解决我的问题。

import { CanActivate, Router } from '@angular/router';
import { AngularFireAuth } from "angularfire2/angularfire2";
import { Injectable } from "@angular/core";
import { Observable } from "rxjs/Rx";
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/take';
@Injectable()
export class RouteGuard implements CanActivate {
    constructor(private auth: AngularFireAuth, private router: Router) {}
    canActivate(): Observable<boolean> {
      return Observable.from(this.auth)
        .take(1)
        .map(state => !!state)
        .do(authenticated => {
      if 
        (!authenticated) this.router.navigate([ '/login' ]);
      })
    }
}

您正在对您的身份服务进行异步调用,这意味着canActivate()在之前返回this.loggedIn 它将其值设置为True或false。而且,由于每次您采用" MyPath"路线this.isLoggedin时,警卫都会被重置为null

现在,为了避免这种行为,您可以使用警卫的布尔外部,并使用该布尔值跟踪是否登录。

感谢 @younesm的答案,我想出了如何解决这个问题。

基本上,您要做的就是将返回的值设置为从开始时将返回的值设置为true,然后由于您仅在false上重定向,因此您可以简单地返回Canactivate()方法末端的值。

请查看下面的此示例,并注意路由反应器:

import { Injectable } from '@angular/core';
import {
  ActivatedRouteSnapshot,
  CanActivate,
  Router,
  RouterStateSnapshot,
} from '@angular/router';
import { Observable } from 'rxjs';
import { AuthService } from '../../auth/auth.service';
@Injectable()
export class PrincipalGuard implements CanActivate {
  profile: any;
  routeActivator: boolean = true;
  constructor(private authService: AuthService, private router: Router) {}
  canActivate(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): boolean | Observable<boolean> | Promise<boolean> {
    this.authService.getSignedInUserProfile().subscribe((profile) => {
      this.profile = profile;
      if (this.profile.title != 'Principal') {
        return this.router.navigate(['/dashboard']);
      } else {
        return this.routeActivator;
      }
    });
    return this.routeActivator;
  }
}

最新更新