【Angular】ルーティングを分割して複数ファイルで管理する【loadChildren】
※下記の内容に不備がありましたら、コメント頂けると幸いです。また、下記の内容をご使用頂ける場合は自己責任でお願いします。
【目次】
背景
Angularのルーティングが複雑になりそうなので、モジュール毎にルーティングを管理することにしました。
構造が分かりやすいようにコンポーネント毎にフォルダを作るのが個人的に好きだからという理由もあります。
ただルーティングに関しては、複数のファイルにまたがって管理していいものなのかどうか知識がないので、今後調べていく必要がありそう。
(Railsではたしか1つのファイルでルーティングを管理していたはず)
ルーティングを複数ファイルで管理する
今回はヒーローアプリをイメージしています。
トップページではヒーロー一覧が表示され、ヒーローを選択すると詳細ページが開きます。
appリポジトリ内にはheroesフォルダ作成しており、その中でもルーティング管理を行えるようにします。
今回の記事の前提として、heroesフォルダは既に作成されていることとします。
index.htmlを編集する
index.htmlのhead要素内にbase要素を追加します。
base要素はルーティングの設定の一つです。
指定したpathに接続した時にルーティングを有効にさせます。
今回は「/」なので、localhostに接続した際にルーティングが有効になります。
src/index.html
<base href="/">
app.component.htmlを編集する
app.component.htmlに「router-outlet」を追加します。
「router-outlet」はpathが一致した際に、それに該当するコンポーネントを表示してくれます。
「router-outlet」はRouterModuleをインポートすれば使えるようになります。
app.component.html
<h1>ヒーロー紹介</h1>
<router-outlet></router-outlet>
app-routing.moduleを作成する
コマンドを使ってapp-routing.moduleを作成します。
$ ng generate module app-routing --flat --module=app
--flatは、固有のフォルダの代わりに、src/appに生成したファイルを置きます。
--module=appは、AppModuleのimports配列に、生成したモジュールを登録するようCLIに指示します。
作成されたファイルは以下のようになっています。
また、app.module.tsでは自動的にAppRoutingModuleが登録されています(掲載割愛)
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
@NgModule({
imports: [
CommonModule
],
declarations: []
})
export class AppRoutingModule { }
app-routing.module.tsを以下のように置き換えます。
app-routing.module.ts
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
const routes: Routes = [
{
path: '',
loadChildren: 'src/app/heroes/heroes.module#HeroesModule',
},
{
path: '**',
component: 'ErrorComponent'
}
];
@NgModule({
imports: [
RouterModule.forRoot(routes)
],
exports: [
RouterModule
]
})
export class AppRoutingModule { }
app-routingで上記のように設定したことで、localhostに接続した時にheroesフォルダの「heroes.module」を参照するようになります。
※localhostでルーティングが有効になっているのは、index.htmlにbase要素で「/」を追加したからです。
heroes-routing.module.tsを作成する
少し順番が逆なような気もしますが、heroesリポジトリ内にheroes-routing.module.tsを作成します。
(本来であれば、heroes.moduleから説明した方が分かりやすいかもです・・・heroes.moduleの編集からしたい場合は、少し下の方を参照してください)
ちょうど良い感じのコマンドが分からないので、heroesフォルダ上で右クリックしてファイル作成を選択します。
ファイル名は「heroes-routing.module.ts」にしましょう。
さらにheroes-routing.module.tsを以下のように置き換えます。
※pathが「show/:id」以下のルーティング関連については説明を省きます。
heroes-routing.module.ts
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { HeroesComponent } from './heroes.component';
import { ShowComponent } from './show/show.component';
import { AboutComponent } from './about/about.component';
const routes: Routes = [
{
path: '' ,
component: HeroesComponent,
},
{
path: 'show/:id',
component: ShowComponent,
children: [
path: 'about',
component: AboutComponent
],
},
];
@NgModule({
imports: [
RouterModule.forChild(routes)
],
exports: [
RouterModule
],
})
export class EventsRoutingModule { }
注意点としてHeroesComponentのpathに文字を入れると、それ以下のpathを参照する際にもその文字がURLに付きます。
例えば、pathに「index」と入力しておくと、path「show」のURLは「localhost/index/show/1」になります。
ちなみに、app-routing.module.tsのloadChildrenのpathで「index」、HeroesComponentのpathでは「''」とした場合のURLは、「localhost/index」になります。
また、app-routing(メインモジュールのルーティング)以外のルーティングでは、ルート情報を追加する場合にはforChildメソッドを使うことを忘れないようにしましょう。
heroes.moduleにルーティングとコンポーネントを追加
heroesモジュールでルーティングとコンポーネントが使えるようにします。
heroes.module
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { HeroesRoutingModule } from './heroes-routing.module';
import { HeroesComponent } from './heroes.component';
@NgModule({
imports: [
HeroesRoutingModule,
CommonModule
],
declarations: [
HeroesComponent,
]
})
export class HeroesModule { }
これでルーティングを分割して複数ファイルで管理することができました。
参考
素晴らしい記事に感謝いたします。