8

当我的用户在屏幕上有脏更改时,我有一个路由守卫来提示他们在他们试图导航离开时保存或丢弃。

但是,如果我因为不活动而将它们注销,我想强制导航并绕过路由守卫(通过丢弃它们的更改),以确保它们的屏幕是空白的。

如何绕过路线守卫?

4

4 回答 4

10

我的解决方案如下:

logout成功注销后的方法,将应用程序重定向到/login路由:

@Injectable
export class AuthService {
  // ...
  logout () {
    // do logout
    this.router.navigate(['/login']);
  }
}

我的后卫如下:

@Injectable
export class DiscardChangesGuard implements CanDeactivate<MyComponent> {

  canDeactivate(component: MyComponent, currentRoute: ActivatedRouteSnapshot,
                currentState: RouterStateSnapshot, nextState?: RouterStateSnapshot): Observable<boolean> | boolean {

    if (nextState.url === '/login') {
      return true; // bypass checks if we are trying to go to /login
    }

    // perform regular checks here
  }
}
于 2017-10-05T11:20:05.083 回答
5

以下是如何在每次导航的基础上强制绕过。就我而言,在用户提交包含帐户信息的表单后,我正在导航回帐户仪表板。

理想情况下,您会检查表单中未保存的更改并基于此绕过,但我的表单还没有该功能。

表单组件:

this.router.navigateByUrl('/', { state: { bypassFormGuard: true } })

路由器保护:

@Injectable()
export class ExitFormGuard implements CanDeactivate<ComponentCanDeactivate> {

   constructor(private router: Router) {}

   canDeactivate(component: ComponentCanDeactivate): boolean | Observable<boolean> {
      if (this.router.getCurrentNavigation()?.extras?.state?.bypassFormGuard) {
         return true
      }

      // perform normal checks
   }
}

于 2020-12-04T12:23:49.267 回答
1

我的目标是绕过路线守卫而不触及应用程序中的每个路线守卫,但我无法做到这一点。最终,我创建了一个新RouteBypassService的注入到每个路由守卫中。 RouteBypassServiceimplements shouldBypass,如果路由守卫应该允许导航出于某些覆盖带外原因(例如授权),则返回 true。在我的情况下shouldBypass,如果没有用户登录,则返回 true。(在他们退出后,无论如何我们都让他们离开屏幕)。

这并不理想,因为每个路由守卫的作者都必须肯定记得添加旁路,但它并不是很纠结。

于 2017-05-15T20:25:19.740 回答
0

我创建了一个类似白名单的东西来写下我想绕过守卫的每条路线

白名单.ts

export const WhiteListedRoutes: string[] = [
  '/route1',
  '/route2',
];

然后在守卫中是这样的:

import { WhiteListedRoutes } from './white-list';

@Injectable({
  providedIn: 'root'
})
export class AuthGuard implements CanActivate {
  constructor(private authService: AuthService, private router: Router) {}

  canActivate(_next: ActivatedRouteSnapshot, _state: RouterStateSnapshot): boolean | Promise<boolean> {
    const route = state.url.split('?')[0];
    const queryParams = _route.queryParams;
    const isWhiteListed = WhiteListedRoutes.findIndex((r: string) => r === route) >= 0;

    return this.status || isWhiteListed || this.router.navigate(['/'], { state: { r: route }, queryParams } );
  }
}
于 2022-01-03T23:00:55.533 回答