为什么 canLoad 函数在重新路由期间会导致无限循环?

Why is canLoad function resulting in infinite loop during reroute?

我在我的 AuthGuard 中使用 Angular 的 canLoad 函数来验证我应用根目录下的延迟加载模块。

如果用户未通过身份验证,则不会加载模块并将用户导航至登录页面。这与 canActivate 一起工作得很好,但在我的 canLoad 应用程序启动期间导致无限循环。

我不确定循环是在哪里或如何产生的,因为我的 auth 组件是另一个模块的一部分,然后是我要加载的模块,并且重定向不是到根目录。我发现了类似的 problems/articles 但他们的案例更加明显。

AppRoutingModule

const routes: Routes = [
{
    path: '',
    component: AdminLayoutComponent,
    canLoad: [AuthGuard],
    loadChildren: () => import('./_layouts/admin-layout/admin-layout.module').then(mod => mod.AdminLayoutModule)
},
{
    path: 'login',
    component: AuthComponent
},
{
    path: '404',
    component: PageNotFoundComponent,
}
];

AuthGaurdService

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

    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
        return this.userService.isAuthenticated.pipe(take(1)).map(auth => {
            if (auth == true) {
                return true;
            }
            console.warn('User not authenticated. ACCESS DENIED.');
            // navigate to login page
            this.router.navigate(['/login']);
            // you can save redirect url so after authing we can move them back to the page they requested
            return false;
        });
    }

    canLoad(route: Route, segments: UrlSegment[]): Observable<boolean> | Promise<boolean> | boolean {
        return this.userService.isAuthenticated.pipe(take(1)).map(auth => {
            if (auth == true) {
                return true;
            }
            console.warn('User not authenticated. ACCESS DENIED.');
            // navigate to login page
            this.router.navigate([route.path + '/login']);
            // you can save redirect url so after authing we can move them back to the page they requested
            return false;
        });
    }
  }

AuthComponent 提交方法

    submitForm(): void {
    this.isSubmitting = true;
    this.errors = {errors: {}};

    const credentials = (this.authType == 'login' ? this.loginForm.value : this.registerForm.value);
    this.userService
        .attemptAuth(this.authType, credentials).subscribe(
        data => {
            console.log('Redirecting to profile');
            // Make profile default
            this.router.navigateByUrl('/profile');
        },
        err => {
            console.log('ERROR: ', err);
            this.errors = err;
            this.isSubmitting = false;
            // Redirect back to register/login
        }
    );

配置中路由的顺序很重要,这是设计使然。路由器在匹配路由时采用先匹配优胜策略,因此更具体的路由应该放在不太具体的路由之上。在上面的配置中,首先列出具有静态路径的路由,然后是与默认路由匹配的空路径路由。通配符路由排在最后,因为它匹配每个 URL,只有在没有其他路由首先匹配时才应选择。 (引自 https://angular.io/guide/router