角度应用中的正确路由

Posted

技术标签:

【中文标题】角度应用中的正确路由【英文标题】:Correct routing in angular application 【发布时间】:2021-12-19 22:36:01 【问题描述】:

我想知道如何在我的应用程序中正确地咬住路由主题。

现在的样子: app-routing.module.ts 文件:

const routes: Routes = [
  
    path: '',
    component: MainLayoutComponent,
    children: [
      
        path: '',
        loadChildren: '../app/modules/home.module#HomeModule'
      ,
      
        path: '',
        loadChildren: '../app/modules/products.module#ProductsModule'
      
    ]
  ,
  
    path: '**',
    redirectTo: '/404'
  
];

我知道它看起来很糟糕。两条相同的路径:''。 但在 ProductsModule 我的路由看起来像这样:

products.routing.ts 文件:

const routes: Routes = [
  
    path: 'products/:id',
    component: ProductDetailsComponent
  ,
  
    path: ':mainCategory',
    component: ProductsComponent
  ,
  
    path: ':mainCategory/:subCategory',
    component: ProductsComponent
  
];

我想做什么:

1. 转到:'/products/12331' 后,加载 ID 为 12331 的 ProductDetailsComponent。

可能它不起作用,因为主模块有路径:''。

将ProductDetailsComponent与ProductsComponent分开是解决这个问题的方法吗?

这样我的 app-routing.module.ts 会看起来:

const routes: Routes = [
  
    path: '',
    component: MainLayoutComponent,
    children: [
      
        path: '',
        loadChildren: '../app/modules/home.module#HomeModule'
      ,
      
        path: 'products',
        loadChildren: '../app/modules/products.module#ProductsModule'
      ,
      
        path: ':mainCategoryId',
        loadChildren: '../app/modules/products.module#CategoriesModule' (adding new module with CategoriesComponent)
      
    ]
  ,
  
    path: '**',
    redirectTo: '/404'
  
];

第二个问题是我正在从后端加载类别。 如何解决路由到不存在的类别的问题? 例如我有类别:

    食品 [饮料、肉类、披萨] 衣服 [鞋子、夹克、帽子]

现在如果我要去:

/Foods/Drinks - 应该加载 CategoriesComponent

/Foods/Shoes - 应该路由到 /404 但如何处理呢? (类别不存在)

/randomName/Drinks - 应该路由到 /404

我该如何解决?也许我的问题很愚蠢,但我正在学习角度:)

【问题讨论】:

【参考方案1】:

您问的是两个截然不同的问题,这并不理想,但我会尽力提供帮助。

对于路由问题,您的第二个路由表更好,但仍然不正确。

children 用于空路径似乎无法达到目的。您还延迟加载 HomeModule 在具有空路径的子路由上。我很确定那是行不通的。如果home.routing.ts 实际上包含子路径,只需将其移至顶层,因为无需延迟加载。

尝试像这样重做:

const routes: Routes = [
    
        path: '',
        component: MainLayoutComponent,
    ,
    
        path: 'home',   // pretending this is from home.module.ts
        component: HomeComponent,
    ,
    
        path: 'products',
        loadChildren: '../app/modules/products.module#ProductsModule'
    ,
    
        path: 'categories',
        loadChildren: '../app/modules/products.module#CategoriesModule'
    ,
    
        path: '**',
        redirectTo: '/404'
    
];

这要简单得多,并且您在启动和运行所有内容时遇到的问题更少。我想说:mainCategoryId 作为***路径通常是一个坏主意,除非你只有一种类型的东西。所以将它们放在categories/:mainCategory 下会更容易理解发生了什么。

现在对于您的第二个问题,您想知道如果给定的类别无效,如何重定向到 404 页面。因为我们将路线更改为categories/:mainCategory,所以我们无需担心您的/randomName/Drinks,因为它已经转到 404。对于您的其他示例,您有几种处理方法。

可能最简单的方法是检查 ProductsComponent 中的参数。

@Component(
    selector: 'products-component',
    templateUrl: './products-component.component.html',
    styleUrls: ['./products-component.component.scss'],
)
export class ProductsComponent 
    public category: string;
    public subCategory: string;

    constructor(private route: ActivatedRoute, private router: Router) 
        this.route.params.subscribe( params => 
            this.category = params['mainCategory'];
            this.subCategory = params['subCategory'];

            // validate categories in some way (either service, local method or something 
            if (!this.isCatValid(this.category) || !this.isCatValid(this.subCategory)) 
                this.router.navigate(['404']);
               
        
    

    this.isCatValid(category: string): boolean 
        // validate category
    

或者,如果您创建一个 categoryService ,您可以确保在任何路由之前预加载并具有调用解析,您可以使用将 CanActivate 路由保护添加到您的类别路由。所以你的 categories.routing.ts 看起来像这样:

const routes: Routes = [
  
    path: ':mainCategory',
    component: ProductsComponent,
    canActivate: [CanActivateCategories]
  ,
  
    path: ':mainCategory/:subCategory',
    component: ProductsComponent,
    canActivate: [CanActivateCategories]
  
];

然后您只需要编写一个 CanActivateCategories 来验证参数并返回 true 或者如果无效则返回另一个 this.router.navigate(['404']);

【讨论】:

以上是关于角度应用中的正确路由的主要内容,如果未能解决你的问题,请参考以下文章

无法从角度路由器获取路径或 url

无法从角度路由器获取路径或URL

角度 4 子路由

如何在使用混合路由时以角度使用 ActivatedRoute?

如何在角度 CLI 中接收当前路由响应?

锚点href vs 角度路由器链接