【问题标题】:Sub-Module child routes not working ("Error: Cannot match any routes.")子模块子路由不起作用(“错误:无法匹配任何路由。”)
【发布时间】:2018-12-16 15:13:45
【问题描述】:

我正在使用 Angular 6.0.3。我有一个名为“Admin”的子模块,包含三个组件。 Admin 的根组件(“AdminComponent”)路由工作正常(path: ""),但我似乎无法触发任何其他路由。为什么 Angular 找不到我的路线?

routes.ts

import { Routes } from "@angular/router";
import { SplashComponent } from "./splash/splash.component";
import { LoginComponent } from "./login/login.component";
import { WatchComponent } from "./watch/watch.component";

import { AdminComponent } from "./admin/admin/admin.component";
import { HomeComponent as AdminHomeComponent } from "./admin/home/home.component";
import { AddSongComponent } from "./admin/add-song/add-song.component";
import { AdminGuard } from "./auth/admin.guard";

export const appRoutes: Routes = [
  {
    path: "",
    children: [
      { path: "", component: SplashComponent, pathMatch: "full" },
      { path: "login", component: LoginComponent, pathMatch: "full" },
      { path: "watch", component: WatchComponent, pathMatch: "full" },
      {
        path: "admin",
        component: AdminComponent,
        pathMatch: "full",
        canActivate: [AdminGuard],
        children: [
          {
            path: "",
            component: AdminHomeComponent,
            pathMatch: "full",
            outlet: "admin"
          },
          {
            path: "add-song",
            component: AddSongComponent,
            pathMatch: "full",
            outlet: "admin"
          }
        ]
      }
    ]
  }
];

admin/admin/admin.component.html

<router-outlet name='admin'></router-outlet>

admin/home/home.component.html

<div>

   <a mat-raised-button [routerLink]="['add-song']">Add new song</a>

</div>

注意:我也试过[routerLink]="[{ outlets: { admin: ['add-song'] } }],仍然找不到路由。

【问题讨论】:

  • 您好,您指定的 router-outlet 可能有问题。您能否提供一个有效的 stackblitz 示例?这样我就可以帮你了。
  • 这个答案对你有帮助吗?

标签: angular routes


【解决方案1】:

Here's a working example of your code,修复只是在除重定向路由之外的所有位置删除pathMatch: 'full'

重定向路由需要一个 pathMatch 属性来告诉路由器如何将 URL 匹配到路由的路径。如果您不这样做,路由器会引发错误。在这个应用程序中,只有当整个 URL 匹配 '' 时,路由器才会选择到 HeroListComponent 的路由,因此将 pathMatch 的值设置为 'full'。

Consider the docs, to learn more about the property.

【讨论】:

    【解决方案2】:

    我认为您的问题与为锚标记生成角度的路径有关。目前您指的是路径“添加歌曲”。 Angular 将此路径视为“localhost:4200/add-song”。如果您想将其路由到 admin/add-song 那么您需要定义完整路径(不知道为什么 Angular 会这样做)。如果你可以试试

     <a mat-raised-button [routerLink]="['admin/add-song']">Add new song</a>
    

    这可能暂时有效,但它不是一个完美的解决方案。 谢谢

    【讨论】:

      【解决方案3】:

      这可能是迟到的回复,但我想专注于一件重要的事情,角度编译器非常聪明,它可以检测你当前所在的根目录。所以如果你从 .html 模板调用任何嵌套路由,它会自动检查您在 url 中的当前路线以及您想要的任何路线都会简单地将其附加到当前路线。

      简单来说,您在admin/home/home.component.html 的代码中尝试执行的操作是您尝试触发add-song 路由,它会给您结果,因为admin/add-song 不存在。不过,这几乎是意料之中的

      共享路线配置。对于儿童和其他一些代码 sn-p。

      children: [
            {
              path: "admin-home",
              component: AdminHomeComponent,
              pathMatch: "full",
              outlet: "admin"
            },
            {
              path: "add-song", 
              component: AddSongComponent, 
              pathMatch: "full",
              outlet: "admin"
            },
            {path: '', 
            redirectTo:'admin-home', 
            pathMatch: 'full'}
          ]
      

      现在从您的admin/home/home.component.html 使用下面的 routerLink

        <div>
          <a mat-raised-button [routerLink]="['/add-song']">Add new song</a>
        </div>
      

      直到现在你试图添加相对路径,特别是在 routerLink 中,它会检测当前路径并将预期路径附加到当前路径的末尾。所以它会给你错误。所以尝试提供绝对路径在你的嵌套路由中。

      但是 this.router.navigate() 方法不会自动理解它的当前路由。它总是从根路由开始路由。即如果你试图从 .ts 文件调用嵌套路径,那么 Angular 将无法识别当前路径.因此,如果您愿意告诉 Angular 哪个是当前路线,那么您可以从 .ts 文件中执行类似的操作

      import { ActivatedRoute, Router } from '@angular/router';
      ...
      constructor(private route: ActivatedRoute, private router: Router) { }
      ...
      this.router.navigate(['./add-song'], {relativeTo: this.route}); 
      

      还有一个像&lt;a mat-raised-button [routerLink]="['add-song']"&gt;Add new song&lt;/a&gt;这和&lt;a mat-raised-button [routerLink]="['./add-song']"&gt;Add new song&lt;/a&gt;一样或者&lt;a mat-raised-button [routerLink]="['../add-song']"&gt;Add new song&lt;/a&gt;这是相对路径,你必须使用绝对路径

      否则,请尝试从没有 relativeTo 属性和相对路径的 .ts 组件调用您的路由。

      希望这对你有用

      【讨论】:

        【解决方案4】:

        我建议您在加载子模块时查看 Lazy-loading 功能,这是当您有很多模块时的正确加载方式。

        在您的情况下,您将管理模块作为子模块,所以这里是路由配置,

         RouterModule.forRoot([
              { path: '', redirectTo: 'splash', pathMatch: 'full' },
              { path: 'splash', component: SplashComponent },
              { path: 'admin', loadChildren: './admin/admin.module#AdminModule' },
              { path: '**', component: NotFoundComponent }
            ], { enableTracing: true })]
        

        而Admin.module的路由如下,

        RouterModule.forChild([
              {
                path: '', component: AdminComponent,
                children: [
        
                  { path: '', component: AdminHomeComponent }
                  ,
                  { path: 'add-song', component:  AddSongComponent}]
              }
          ])
          ]
        

        WORKING STACKBLITZ DEMO

        路线:

        飞溅

        管理员

        Admin-AddSong

        【讨论】:

        • 我想用 url 分隔我的管理员和前端部分。对于管理员,我想要这样的:http://localhost:4200/admin/dashboard。 Url 与 routs 匹配,但它在控制台中打印错误 http://localhost:4200/admin/runtime.js net::ERR_ABORTED 404 (Not Found)。有什么想法吗?
        【解决方案5】:

        您是否尝试过在自己的模块中创建与管理相关的组件? 然后你可以创建一个admin-routing.module.ts

        const adminRoutes: Routes = [
          {
            path: '',
            component: AdminComponent,
            children: [
              {
                path: '',
                children: [
                  { path: 'add-song', component: AddSongComponent },
                  { path: 'something-else', component: SomeOtherComponent },
                  { path: '', component: AdminDefaultComponent }
                ]
              }
            ]
          }
        ];
        
        @NgModule({
          imports: [ 
            RouterModule.forChild(adminRoutes)
          ],
          exports: [
            RouterModule
          ]
        })
        export class AdminRoutingModule {}
        

        然后在您的主要app-routing.module 中您可以将其称为

        const appRoutes: Routes = [
          { path: '', component: SplashComponent },
          { path: 'login', component: LoginComponent },
          {
            path: 'admin',
            loadChildren: 'app/admin/admin.module#AdminModule',
          },
          { path: '**', component: SomeOtherComponent }
        ];
        
        @NgModule({
          imports: [
            RouterModule.forRoot(appRoutes)
          ],
          exports: [
            RouterModule
          ],
        })
        export class AppRoutingModule { }
        

        编辑:我注意到您确实创建了自己的子模块,因此您需要为该子模块创建一个路由模块。

        【讨论】:

          【解决方案6】:

          问题是您没有为 path ""

          定义任何组件
          import { Routes } from "@angular/router";
          import { SplashComponent } from "./splash/splash.component";
          import { LoginComponent } from "./login/login.component";
          import { WatchComponent } from "./watch/watch.component";
          
          import { AdminComponent } from "./admin/admin/admin.component";
          import { HomeComponent as AdminHomeComponent } from "./admin/home/home.component";
          import { AddSongComponent } from "./admin/add-song/add-song.component";
          import { AdminGuard } from "./auth/admin.guard";
          
          export const appRoutes: Routes = [
            {
              path: "",
              component: SplashComponent,
              children: [
                { path: "login", component: LoginComponent, pathMatch: "full" },
                { path: "watch", component: WatchComponent, pathMatch: "full" },
                {
                  path: "admin",
                  component: AdminComponent,
                  pathMatch: "full",
                  canActivate: [AdminGuard],
                  children: [
                    {
                      path: "",
                      component: AdminHomeComponent,
                      pathMatch: "full",
                      outlet: "admin"
                    },
                    {
                      path: "add-song",
                      component: AddSongComponent,
                      pathMatch: "full",
                      outlet: "admin"
                    }
                  ]
                }
              ]
            }
          ];
          

          【讨论】:

          • 我把顶层改成了component: SplashComponent,现在除了""外找不到其他路由了。
          • 根据您的项目,如果单击 admin / add-song,需要什么路径? @zakdances
          • 应该加载路径为“admin/add-song”的AddSongComponent
          • 好的,再问一个问题,你的默认组件是什么?当路径是“”?
          • "" 处的根组件应该是 SplashComponent。
          猜你喜欢
          • 2019-03-28
          • 2022-01-25
          • 2016-11-11
          • 1970-01-01
          • 1970-01-01
          • 2020-01-13
          • 2017-11-13
          • 2016-10-01
          • 1970-01-01
          相关资源
          最近更新 更多