web-dev-qa-db-ja.com

サブモジュールの子ルートが機能しない(「エラー:どのルートにも一致しません。」)

Angular 6.0.3を使用しています。「Admin」というサブモジュールと3つのコンポーネントがあります。Adminのルートコンポーネント(「AdminComponent」)ルートは正常に機能します(path: "")、しかし、私は他のどれも引き起こさないようです。 Angularルートが見つからないのはなぜですか?

route.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
zakdances

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

11
Sajeetharan

独自のモジュールで管理関連コンポーネントを作成しようとしましたか?次に、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
DavidZ

これは返答が遅いかもしれませんが、1つの重要なことに焦点を当てたいと思います。angularコンパイラは、現在どのルート上にいるかを検出する非常にスマートです。 htmlテンプレートは、URL内の現在のルートを自動的にチェックし、これが必要などのルートでも、これを現在のルートに追加するだけです。

簡単に言えば、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>

これまでは相対パスを追加しようとしていましたが、angular特に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}); 

もう1つは<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>これは相対パスです。絶対パスを使用する必要があります

それ以外の場合は、relativeToプロパティと相対パスなしで.tsコンポーネントからルートを呼び出してみてください。

これがうまくいくことを願っています

1
Prasanna Sasne

問題は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"
          }
        ]
      }
    ]
  }
];
1
Debojyoti

これはコードの実際の例です 、修正はリダイレクトルートを除くすべての場所でpathMatch: 'full'を削除するだけでした。

リダイレクトルートには、URLをルートのパスに一致させる方法をルーターに指示するためのpathMatchプロパティが必要です。そうでない場合、ルーターはエラーをスローします。このアプリでは、ルーターは、URL全体が ''と一致する場合にのみ、HeroListComponentへのルートを選択する必要があるため、pathMatch値を「full」に設定します。

プロパティについて詳しくは、ドキュメントを検討してください。

0
k.s.

あなたの問題は、angularアンカータグ用に生成されているパスに関連していると思います。現在、「add-song」というパスを参照しています。Angularは、このパスは "localhost:4200/add-song"として指定します。これをadmin/add-songにルーティングする場合は、フルパスを定義する必要があります(理由angular doこれです。

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

これはしばらくはうまくいくかもしれませんが、完璧な解決策ではありません。ありがとう

0
Ali Khan