Angular 16 中基于平台的重定向

问题描述 投票:0回答:2

我的 a 有一个模块,其中包含自己的子路由。本质上,该页面的唯一内容是标题和一些链接到我的路由的材料选项卡,因此我只会显示其中之一。但是,无论我在桌面上还是在移动设备上,我希望登陆选项卡有所不同。

我有一个名为 ToolService 的服务,其中包含 ToolService.isDesktopOrTablet() 方法,我通常用它来进行平台检测。

在意识到我希望redirectTo指向移动设备上的“列表”而不是“树”之前,我的路由模块看起来像这样

export const routes: Routes = [
  {
    path: '',
    component: ExampleComponent,
    children: [{
      path: '',
      redirectTo: 'tree',
      pathMatch: 'full',
    }, {
      path: 'tree',
      component: ExampleTreeComponent,
      title: 'Example Title',
    }, {
      path: 'list',
      component: ExampleListComponent,
      title: 'Example Title',
    }]
  }
]

@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [],
})
export class ExampleRoutingModule {
}

我尝试的第一件事是使用基于类别的守卫。就在那时,我了解到 Angular 15 中基于类的守卫已被弃用,取而代之的是功能性守卫。

我尝试的第二件事是使用功能性守卫,但我收到了一条警告消息,告诉我 canActivate 和 redirectTo 不能很好地配合使用,因为重定向是在守卫之前处理的。

这让我想到了我尝试的第三个解决方案,解析器:

export const exampleResolver: ResolveFn<string> = (): string => inject(ToolService).isDesktopOrTablet() ? 'tree' : 'list'

export const routes: Routes = [
  {
    path: '',
    component: ExampleComponent,
    children: [{
      path: '',
      redirectTo: '',
      pathMatch: 'full',
      resolve: {
        redirectTo: exampleResolver
      },
    }, {
      path: 'tree',
      component: ExampleTreeComponent,
      title: 'Example Title',
    }, {
      path: 'list',
      component: ExampleListComponent,
      title: 'Example Title',
    }]
  }
]

@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [],
  providers: [ToolService]
})
export class ExampleRoutingModule {
}

这似乎不会引发任何错误消息,但它似乎也没有执行任何操作。当我导航到主路线时,我的应用程序停留在 '' 路线上,而没有实际重定向到任何内容,就好像解析器从未执行过一样,这让我想到了我的问题:

  1. 我的解析器是否在某些方面不正确?
  2. 解析器是适合这项工作的工具吗?
  3. 如果是的话?我做错了什么?
  4. 如果没有,我应该用什么来代替?我是不是太早放弃守卫了?
angular typescript routes angular2-routing
2个回答
0
投票

说到重定向,它属于

guards
的范畴,所以你可以编写一个canActivateFn来根据平台类型进行重定向。代码的粗略估计如下所示!

export const platformRedirectGuard: CanActivateFn = (
  next: ActivatedRouteSnapshot,
  state: RouterStateSnapshot
) => { 
  const toolService = inject(ToolService);
  const router = inject(Router);
  const path = toolService.isDesktopOrTablet() ? 'tree' : 'list';
  return router.navigate([path]); // you need to fine tune this, because the solution that works might need different variations, like relative to activated route, etc, but guards are the way to go!
};

路由

export const routes: Routes = [
  {
    path: '',
    component: ExampleComponent,
    children: [{
      path: '',
      redirectTo: '',
      pathMatch: 'full',
      canActivate: [platformRedirectGuard], // <- changed here!
    }, {
      path: 'tree',
      component: ExampleTreeComponent,
      title: 'Example Title',
    }, {
      path: 'list',
      component: ExampleListComponent,
      title: 'Example Title',
    }]
  }
]

@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [],
  providers: [ToolService]
})
export class ExampleRoutingModule {
}

0
投票

我会和

CanActivate
守卫一起去。

canActivate() {
   if(isMobile) {
     return this.router.createUrlTree(['list']);
   } else {
     return `true`
   }
}
© www.soinside.com 2019 - 2024. All rights reserved.