Angular2 で 'router-outlet' エラーを解決するためのサンプルコード
Angular2 で発生する "router-outlet" エラーの原因と解決策
Angular2 で "router-outlet" エラーが発生する場合、主に以下の2つの原因が考えられます。
- ルーティングモジュールのインポート不足
- router-outlet コンポーネントの宣言漏れ
Angular2 のルーティング機能を利用するには、RouterModule
モジュールをインポートする必要があります。このモジュールは、ルーティングの設定やコンポーネントの読み込みなどを担います。
解決策
以下のいずれかの方法で、RouterModule
モジュールをインポートします。
- AppModule にインポート
import { RouterModule } from '@angular/router';
@NgModule({
imports: [
RouterModule.forRoot(routes) // routes: ルーティング設定
],
declarations: [
AppComponent,
// その他のコンポーネント
],
bootstrap: [AppComponent]
})
export class AppModule {}
ルーティング設定を別モジュールに定義している場合は、そのモジュールに RouterModule
モジュールをインポートします。
import { RouterModule } from '@angular/router';
@NgModule({
imports: [
RouterModule.forChild(routes) // routes: ルーティング設定
],
declarations: [
// ルーティング対象のコンポーネント
],
exports: [
RouterModule // ルーティングモジュールをエクスポート
]
})
export class RoutingModule {}
router-outlet
コンポーネントは、ルーティングされたコンポーネントを挿入する場所を指定する特殊なコンポーネントです。このコンポーネントを宣言していない場合、エラーが発生します。
以下のいずれかの方法で、router-outlet
コンポーネントを宣言します。
- AppModule に宣言
import { RouterModule } from '@angular/router';
@NgModule({
imports: [
RouterModule.forRoot(routes)
],
declarations: [
AppComponent,
router-outlet // router-outlet コンポーネントを宣言
],
bootstrap: [AppComponent]
})
export class AppModule {}
import { RouterModule } from '@angular/router';
@NgModule({
imports: [
RouterModule.forChild(routes)
],
declarations: [
router-outlet // router-outlet コンポーネントを宣言
],
exports: [
RouterModule,
router-outlet // router-outlet コンポーネントをエクスポート
]
})
export class RoutingModule {}
- 上記以外にも、
router-outlet
セレクタの誤りなどが原因でエラーが発生する場合があります。エラーメッセージをよく確認し、適切な修正を行ってください。
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { AppComponent } from './app.component';
import { HomeComponent } from './home/home.component';
import { AboutComponent } from './about/about.component';
const routes: Routes = [
{ path: '', component: HomeComponent },
{ path: 'about', component: AboutComponent }
];
@NgModule({
declarations: [
AppComponent,
HomeComponent,
AboutComponent
],
imports: [
RouterModule.forRoot(routes)
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
app.component.html
<div class="container">
<nav>
<a routerLink="/">Home</a>
<a routerLink="/about">About</a>
</nav>
<router-outlet></router-outlet>
</div>
<h1>Home</h1>
<p>This is the home page.</p>
<h1>About</h1>
<p>This is the about page.</p>
このコードの説明
home.component.html
とabout.component.html
は、それぞれホームと詳細ページのコンポーネントのテンプレートです。app.component.html
では、router-outlet
コンポーネントを配置し、ルーティングされたコンポーネントが挿入される場所を指定しています。app.module.ts
では、RouterModule
モジュールをインポートし、ルーティングの設定を定義しています。
このコードを実行するには
- Angular CLI を使用して新しいプロジェクトを作成します。
- 上記のコードを
app.module.ts
、app.component.html
、home.component.html
、about.component.html
ファイルに保存します。 ng serve
コマンドを実行して、アプリケーションを起動します。
このコードで "router-outlet" エラーが発生しないことを確認してください。
- このコードはあくまで一例です。アプリケーションの要件に合わせて、コードを適宜修正してください。
router-outlet
は、Angular のコアモジュールに含まれるコンポーネントです。しかし、Webコンポーネントとして実装されているため、アプリケーションでカスタム要素スキーマを使用していない場合は、エラーが発生する可能性があります。
この問題を解決するには、アプリケーションの @NgModule
デコレータの schemas
プロパティに CUSTOM_ELEMENTS_SCHEMA
を追加します。
@NgModule({
imports: [
RouterModule.forRoot(routes)
],
declarations: [
AppComponent,
router-outlet // router-outlet コンポーネントを宣言
],
bootstrap: [AppComponent],
schemas: [CUSTOM_ELEMENTS_SCHEMA] // カスタム要素スキーマを追加
})
export class AppModule {}
ルーティングモジュールのエクスポート
ルーティング設定を別モジュールに定義している場合は、そのモジュールをエクスポートする必要があります。
import { RouterModule } from '@angular/router';
@NgModule({
imports: [
RouterModule.forChild(routes)
],
declarations: [
router-outlet // router-outlet コンポーネントを宣言
],
exports: [
RouterModule,
router-outlet // router-outlet コンポーネントをエクスポート
]
})
export class RoutingModule {}
ngModule を使用する
ngModule
ディレクティブを使用して、コンポーネント内でルーティングモジュールをインポートすることもできます。
import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
@Component({
selector: 'app-my-component',
template: `
<div>
<router-outlet></router-outlet>
</div>
`,
})
@NgModule({
imports: [
RouterModule.forChild([
{ path: '', component: HomeComponent },
{ path: 'about', component: AboutComponent }
])
]
})
export class MyComponent {}
loadChildren プロパティを使用する
loadChildren
プロパティを使用して、非同期的にルーティングモジュールを読み込むこともできます。
const routes: Routes = [
{
path: 'lazy',
loadChildren: () => import('./lazy-routing.module').then(m => m.LazyRoutingModule)
}
];
forRoot と forChild メソッドを使い分ける
forRoot
メソッドは、ルートモジュールをインポートするために使用されます。一方、forChild
メソッドは、子モジュールをインポートするために使用されます。
- 子モジュール
特定のパスに関連するルーティング設定を定義します。 - ルートモジュール
アプリケーション全体のルーティング設定を定義します。
ルーティング構成を確認する
ルーティング構成に誤りがないことを確認してください。特に、パス名とコンポーネント名のスペルミスに注意してください。
キャッシュをクリアする
ブラウザのキャッシュをクリアすると、問題が解決する場合があります。
開発ツールを使用する
ブラウザの開発ツールを使用して、エラーの詳細を確認することができます。
angular angular2-routing