You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular 15路由参数有效性验证及用户不存在场景处理

Angular 15 用户路由验证与NotFound组件渲染方案

初始路由配置

app-routing.module

export const routes: Routes = [
  {
    path: '',
    component: ApplicationLayoutComponent,
    children: [
      {
        path: 'user',
        loadChildren: () => import('./modules/user/user.module').then(m => m.UserModule)
      },
      {
        // 其他模块路由...
      }
    ]
  },
  {
    path: '**',
    redirectTo: '' // 重定向到首页
  }
];

user-routing.module

export const routes: Routes = [
  {
    path: '',
    children: [
      {
        path: ':id',
        component: UserComponent,
        children: [
          { path: 'profile', component: UserProfileComponent },
          { path: 'settings', component: UserSettingsComponent },
          { path: 'notifications', component: UserNotificationsComponent },
          {
            // 其他子路由...
          }
        ]
      }
    ]
  }
];

上述配置生成的路由包括:

  • /user/**xxx**/profile
  • /user/**xxx**/settings
  • /user/**xxx**/settings/some-setting/...
  • /user/**xxx**/...

需求目标

  • 访问/user/:id层级下的任何路由时,若指定用户不存在,渲染UserNotFoundComponent;
  • 用户存在时,所有子路由组件都能访问到验证过程中获取的User对象;
  • 禁止用户手动访问专门的NotFound路由,且无需修改URL来切换状态。

尝试过的方案

曾考虑在user-routing.module中添加NotFound路由:

export const routes: Routes = [
  {
    path: '',
    children: [
      {
        path: ':id',
        component: UserComponent,
        children: [
          { path: 'profile', component: UserProfileComponent },
          {
            // 其他子路由...
          }
        ]
      }
    ]
  },
  {
    path: '404',
    component: UserNotFoundComponent
  }
];

但无法确定重定向时机,且无法禁止用户手动访问/user/404。

最终实现方案

1. 创建用户Resolver

Resolver负责获取用户信息,若用户不存在则返回null:

export function UserResolver(): ResolveFn<User | null> {
  return (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => {
    const service = inject(UserService);
    const userId = parseInt(route.paramMap.get('id')!);
  
    return service.getUser(userId)
      .pipe(
        catchError(() => {
          return of(null);
        })
      );
  }
}

2. 更新user-routing.module

将Resolver绑定到/:id路由上:

export const routes: Routes = [
  {
    path: '',
    children: [
      {
        path: ':id',
        resolve: {
          user: UserResolver()
        },
        component: UserComponent,
        children: [
          { path: 'profile', component: UserProfileComponent },
          { path: 'settings', component: UserSettingsComponent },
          { path: 'notifications', component: UserNotificationsComponent },
          {
            // 其他子路由...
          }
        ]
      }
    ]
  }
];

3. 改造UserComponent

在组件中订阅路由数据,获取Resolver返回的用户对象:

export class UserComponent implements OnInit {
  public user?: User;
  
  constructor(
    private readonly route: ActivatedRoute
  ) {}
  
  public ngOnInit(): void {
    this.route.data.subscribe((data: Data) => {
      this.user = data['user'];
    });
  }
}

4. 调整UserComponent模板

根据用户是否存在,决定渲染子路由出口还是NotFound组件:

<router-outlet *ngIf="user; else userNotFound"></router-outlet>
<ng-template #userNotFound>
  <user-not-found />
</ng-template>

实现效果

  • 访问/user/:id下的任意路径时,Resolver都会触发并从后端获取用户信息;
  • UserComponent作为子组件容器,初始化时检查用户有效性:有效则加载对应子路由组件,无效则直接显示NotFound提示,无需跳转路由或修改URL,避免了用户手动访问特定NotFound路由的问题;
  • 用户有效时,子路由组件可通过ActivatedRoute的data属性获取到User对象。

内容的提问来源于stack exchange,提问作者GomalId

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 07:17:13