子模块子路由不起作用(“错误:无法匹配任何路由。”)

时间:2018-07-09 00:40:44

标签: angular routes

我正在使用Angular 6.0.3。我有一个名为“ 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'] } }],但仍然找不到路由。

6 个答案:

答案 0 :(得分:10)

我建议您在加载子模块时查看 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

路线:

飞溅

管理员

管理员添加歌曲

答案 1 :(得分:2)

您是否尝试过在自己的模块中创建与Admin相关的组件? 然后,您可以创建一个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 { }

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

答案 2 :(得分:1)

问题是您没有为路径“”

定义任何组件
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"
          }
        ]
      }
    ]
  }
];

答案 3 :(得分:1)

这可能是迟到的回复,但是我想重点关注一件重要的事情,Angular编译器非常聪明,它可以检测到您当前在哪个根上。因此,如果您从.html模板调用任何嵌套的路由,它将自动检查您网址中的当前路线以及您想要的路线,只需将其附加到当前路线即可。

简单来说,您试图在admin/home/home.component.html中的代码中尝试触发add-song路由,这将为您提供结果,因为admin/add-song不存在。虽然这是非常期望的

共享路由配置。用于儿童和其他一些代码段。

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中的angular中,它将检测当前路径并将期望的路径附加到当前路径的末尾,因此会给您错误,因此请尝试提供绝对路径在您的嵌套路线中。

但是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}); 

还有另一件事,例如<a mat-raised-button [routerLink]="['add-song']">Add new song</a><a mat-raised-button [routerLink]="['./add-song']">Add new song</a>相同,或者<a mat-raised-button [routerLink]="['../add-song']">Add new song</a>这是相对路径,必须使用绝对路径

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

希望这可能对您有用

答案 4 :(得分:0)

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

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

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

答案 5 :(得分:0)

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.