【问题标题】:Angular4 Routing: Force Navigation By Bypassing Route GuardAngular4 路由:绕过路由守卫强制导航
【发布时间】:2017-10-01 16:36:32
【问题描述】:

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

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

如何绕过路线守卫?

【问题讨论】:

    标签: angular angular4-router


    【解决方案1】:

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

    white-list.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 } );
      }
    }
    

    【讨论】:

      【解决方案2】:

      您可以通过以下方式强制绕过每个导航。在我的情况下,我在用户提交包含帐户信息的表单后导航回帐户仪表板。

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

      表单组件:

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

      【讨论】:

      【解决方案3】:

      我的解决方案如下:

      我的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
        }
      }
      

      【讨论】:

        【解决方案4】:

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

        不是很理想,因为每一个路由守卫的作者都要肯定记得加旁路,但也不是很纠结。

        【讨论】:

          猜你喜欢
          • 2021-06-01
          • 2019-10-21
          • 2021-10-04
          • 2019-02-04
          • 2018-12-04
          • 1970-01-01
          • 2018-11-14
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多