このトピックでは、Angularルーターをアプリケーションに追加することと関連する一般的なタスクの多くを実装する方法について説明します。
ルーティングが有効なアプリケーションの生成
次のコマンドは、Angular CLIを使用して、アプリケーションルートを含む基本的なAngularアプリケーションを生成します。次の例では、アプリケーション名は routing-app
です。
ng new routing-app
ルーティング用のコンポーネントの追加
Angularルーターを使用するには、アプリケーションに少なくとも2つのコンポーネントが必要です。これにより、一方のコンポーネントからもう一方のコンポーネントにナビゲートできます。 CLIを使用してコンポーネントを作成するには、コマンドラインで次のように入力します。ここで、first
はコンポーネントの名前です。
ng generate component first
この手順を2番目のコンポーネントに対して繰り返しますが、異なる名前を付けます。ここでは、新しい名前は second
です。
ng generate component second
CLIは自動的に Component
を追加するため、first-component
と書くと、コンポーネントは FirstComponentComponent
になります。
base href
このガイドは、CLIにより生成されたAngularアプリケーションで動作します。手動で作業している場合は、index.html
ファイルの <head>
に <base href="/">
があることを確認してください。
これは、app
フォルダーがアプリケーションルートであり、"/"
を使用することを前提としています。
新しいコンポーネントのインポート
新しいコンポーネントを使用するには、ファイルの先頭に示すように、app.routes.ts
にインポートします。
import {FirstComponent} from './first/first.component';import {SecondComponent} from './second/second.component';
基本的なルートの定義
ルートを作成するには、3つの基本的なビルディングブロックがあります。
ルートを app.config.ts
にインポートし、provideRouter
関数に追加します。以下は、CLIを使用したデフォルトの ApplicationConfig
です。
export const appConfig: ApplicationConfig = { providers: [provideRouter(routes)]};
Angular CLIはこの手順を実行します。ただし、手動でアプリケーションを作成している場合、または既存のCLI以外のアプリケーションで作業している場合は、インポートと構成が正しいことを確認してください。
-
ルートの
Routes
配列を設定するAngular CLIはこの手順を自動的に実行します。
import { Routes } from '@angular/router';export const routes: Routes = [];
-
Routes
配列にルートを定義するこの配列の各ルートは、2つのプロパティを含むJavaScriptオブジェクトです。最初のプロパティ
path
は、ルートのURLパスを定義します。2番目のプロパティcomponent
は、対応するパスにAngularが使用するコンポーネントを定義します。const routes: Routes = [ { path: 'first-component', component: FirstComponent }, { path: 'second-component', component: SecondComponent },];
-
アプリケーションにルートを追加する
ルートを定義したので、アプリケーションに追加します。まず、2つのコンポーネントへのリンクを追加します。ルートを追加するアンカータグを
routerLink
属性に割り当てます。属性の値を、ユーザーが各リンクをクリックしたときに表示するコンポーネントに設定します。次に、コンポーネントテンプレートを更新して<router-outlet>
を含めます。この要素は、Angularに選択したルートのコンポーネントでアプリケーションビューを更新するよう通知します。<h1>Angular Router App</h1><nav> <ul> <li><a routerLink="/first-component" routerLinkActive="active" ariaCurrentWhenActive="page">First Component</a></li> <li><a routerLink="/second-component" routerLinkActive="active" ariaCurrentWhenActive="page">Second Component</a></li> </ul></nav><!-- The routed views render in the <router-outlet>--><router-outlet></router-outlet>
AppComponent
のimports
配列にRouterLink
、RouterLinkActive
、RouterOutlet
を追加する必要もあります。@Component({ selector: 'app-root', standalone: true, imports: [CommonModule, RouterOutlet, RouterLink, RouterLinkActive], templateUrl: './app.component.html', styleUrls: ['./app.component.css']})export class AppComponent { title = 'routing-app';}
ルートの順序
ルートの順序は重要です。なぜなら、Router
はルートの照合時に最初に一致したものが勝ちという戦略を使用するため、より具体的なルートは、より一般的なルートよりも上に配置する必要があるからです。
静的なパスを持つルートを最初にリストし、次に空のパスルートをリストします。これは、デフォルトのルートと一致します。
ワイルドカードルート は、最後に来ます。これは、すべてのURLと一致します。Router
は、他のルートが最初に一致しない場合にのみ、このルートを選択します。
ルート情報の取得
多くの場合、ユーザーがアプリケーションをナビゲートするときに、一方のコンポーネントからもう一方のコンポーネントに情報を渡す必要があります。
たとえば、食料品のショッピングリストを表示するアプリケーションを考えてみてください。
リストの各アイテムには、一意の id
があります。
アイテムを編集するには、ユーザーは[編集]ボタンをクリックします。これにより、EditGroceryItem
コンポーネントが開きます。
そのコンポーネントは、食料品アイテムの id
を取得して、ユーザーに正しい情報を表示できるようにする必要があります。
ルートを使用して、このタイプの情報をアプリケーションコンポーネントに渡します。
これを行うには、provideRouter
を使用した withComponentInputBinding 機能、または RouterModule.forRoot
の bindToComponentInputs
オプションを使用します。
ルートから情報を入手するには:
-
withComponentInputBinding
を追加するprovideRouter
メソッドにwithComponentInputBinding
機能を追加します。providers: [ provideRouter(appRoutes, withComponentInputBinding()),]
-
コンポーネントに
Input
を追加するパラメータの名前と一致する
Input
を持つようにコンポーネントを更新します。@Input()set id(heroId: string) { this.hero$ = this.service.getHero(heroId);}
NOTE: すべてのルートデータを、キーと値のペアでコンポーネントの入力にバインドできます。静的なルートデータ、解決されたルートデータ、パスパラメータ、マトリックスパラメータ、クエリパラメータです。 親コンポーネントのルート情報を使用する場合は、ルーターの
paramsInheritanceStrategy
オプションを設定する必要があります。withRouterConfig({paramsInheritanceStrategy: 'always'})
ワイルドカードルートの設定
正常に機能するアプリケーションは、ユーザーがアプリケーションに存在しない部分にナビゲートしようとした場合、正常に処理する必要があります。 アプリケーションにこの機能を追加するには、ワイルドカードルートを設定します。 Angularルーターは、要求されたURLがルーターパスと一致しない場合、このルートを選択します。
ワイルドカードルートを設定するには、routes
定義に次のコードを追加します。
{ path: '**', component:
2つのアスタリスク **
は、Angularにこの routes
定義がワイルドカードルートであることを示します。
component
プロパティには、アプリケーション内の任意のコンポーネントを定義できます。
一般的な選択肢としては、アプリケーション固有の PageNotFoundComponent
があります。これは、ユーザーに 404 ページを表示 するために定義できます。または、アプリケーションのメインコンポーネントへのリダイレクトです。
ワイルドカードルートは、最後のルートです。これは、すべてのURLと一致します。
ルートの順序が重要な理由の詳細については、ルートの順序 を参照してください。
404 ページの表示
404ページを表示するには、ワイルドカードルート を設定します。このルートの component
プロパティは、404ページに使用したいコンポーネントに設定します。
const routes: Routes = [ { path: 'first-component', component: FirstComponent }, { path: 'second-component', component: SecondComponent }, { path: '**', component: PageNotFoundComponent }, // Wildcard route for a 404 page];
path
が **
の最後のルートは、ワイルドカードルートです。
ルーターは、要求されたURLがリストの先頭にあるパスと一致しない場合、このルートを選択し、ユーザーを PageNotFoundComponent
に送信します。
リダイレクトの設定
リダイレクトを設定するには、リダイレクト元の path
、リダイレクト先の component
、およびルーターにURLとどのように一致させるかを指示する pathMatch
値を指定してルートを構成します。
const routes: Routes = [ { path: 'first-component', component: FirstComponent }, { path: 'second-component', component: SecondComponent }, { path: '', redirectTo: '/first-component', pathMatch: 'full' }, // redirect to `first-component` { path: '**', component: PageNotFoundComponent }, // Wildcard route for a 404 page];
この例では、3番目のルートはリダイレクトです。そのため、ルーターは first-component
ルートをデフォルトで選択します。
このリダイレクトは、ワイルドカードルートの前にあることに注意してください。
ここでは、path: ''
は、初期の相対URL (''
) を使用するという意味です。
場合によっては、リダイレクトは単純な静的なリダイレクトではありません。
redirectTo
プロパティは、文字列または UrlTree
を返す、より複雑なロジックを持つ関数にもできます。
const routes: Routes = [ { path: "first-component", component: FirstComponent }, { path: "old-user-page", redirectTo: ({ queryParams }) => { const errorHandler = inject(ErrorHandler); const userIdParam = queryParams['userId']; if (userIdParam !== undefined) { return `/user/${userIdParam}`; } else { errorHandler.handleError(new Error('Attempted navigation to user page without user ID.')); return `/not-found`; } }, }, { path: "user/:userId", component: OtherComponent },];
ネストしたルート
アプリケーションがより複雑になるにつれて、ルートコンポーネント以外のコンポーネントを基準とするルートを作成したい場合があります。
これらのタイプのネストしたルートは、子ルートと呼ばれます。
これは、AppComponent
にある <router-outlet>
に加えて、アプリケーションに2番目の <router-outlet>
を追加することを意味します。
この例では、child-a
と child-b
の2つの追加の子コンポーネントがあります。
ここでは、FirstComponent
には独自の <nav>
と、AppComponent
にあるものに加えて2番目の <router-outlet>
があります。
<h2>First Component</h2><nav> <ul> <li><a routerLink="child-a">Child A</a></li> <li><a routerLink="child-b">Child B</a></li> </ul></nav><router-outlet></router-outlet>
子ルートは、path
と component
の両方を持つ必要があるという点で、他のルートと同じです。
違いは、子ルートを親ルート内の children
配列に配置することです。
const routes: Routes = [ { path: 'first-component', component: FirstComponent, // this is the component with the <router-outlet> in the template children: [ { path: 'child-a', // child route path component: ChildAComponent, // child route component that the router renders }, { path: 'child-b', component: ChildBComponent, // another child route component that the router renders }, ], },];
ページタイトルの設定
アプリケーションの各ページには、ブラウザ履歴で識別できるように、一意のタイトルを設定する必要があります。
Router
は、Route
構成の title
プロパティを使用して、ドキュメントのタイトルを設定します。
const routes: Routes = [ { path: 'first-component', title: 'First component', component: FirstComponent, // this is the component with the <router-outlet> in the template children: [ { path: 'child-a', // child route path title: resolvedChildATitle, component: ChildAComponent, // child route component that the router renders }, { path: 'child-b', title: 'child b', component: ChildBComponent, // another child route component that the router renders }, ], },];const resolvedChildATitle: ResolveFn<string> = () => Promise.resolve('child a');
HELPFUL: title
プロパティは、静的なルート data
や、ResolveFn
を実装する動的な値と同じルールに従います。
TitleStrategy
を拡張して、カスタムタイトル戦略を提供できます。
@Injectable({providedIn: 'root'})export class TemplatePageTitleStrategy extends TitleStrategy { constructor(private readonly title: Title) { super(); } override updateTitle(routerState: RouterStateSnapshot) { const title = this.buildTitle(routerState); if (title !== undefined) { this.title.setTitle(`My Application | ${title}`); } }}export const appConfig: ApplicationConfig = { providers: [ provideRouter(routes), {provide: TitleStrategy, useClass: TemplatePageTitleStrategy}, ]};
相対パスの使用
相対パスを使用すると、現在のURLセグメントを基準とするパスを定義できます。
次の例は、別のコンポーネント second-component
への相対ルートを示しています。
FirstComponent
と SecondComponent
はツリー内で同じレベルにありますが、SecondComponent
へのリンクは FirstComponent
内に配置されているため、ルーターはレベルを1つ上に移動してから2番目のディレクトリに移動して SecondComponent
を見つける必要があります。
SecondComponent
へのパス全体を書き出すのではなく、../
表記を使用してレベルを1つ上に移動します。
<h2>First Component</h2><nav> <ul> <li><a routerLink="../second-component">Relative Route to second component</a></li> </ul></nav><router-outlet></router-outlet>
../
に加えて、./
または先頭にスラッシュがないものを、現在のレベルを指定するために使用します。
相対ルートの指定
相対ルートを指定するには、NavigationExtras
の relativeTo
プロパティを使用します。
コンポーネントクラスで、@angular/router
から NavigationExtras
をインポートします。
次に、ナビゲーションメソッドで relativeTo
を使用します。
ここでは、items
を含むリンクパラメータ配列の後に、relativeTo
プロパティが ActivatedRoute
(これは this.route
) に設定されたオブジェクトを追加します。
goToItems() { this.router.navigate(['items'], { relativeTo: this.route });}
navigate()
の引数は、ルーターに、現在のルートを基準にして items
を追加するよう構成します。
goToItems()
メソッドは、宛先URIをアクティブなルートを基準として解釈し、items
ルートにナビゲートします。
クエリパラメータとフラグメントへのアクセス
場合によっては、アプリケーションの機能で、ルートの一部、たとえばクエリパラメータやフラグメントにアクセスする必要があります。
この段階のTour of Heroesアプリケーションでは、リストビューが使用され、ヒーローをクリックすると詳細が表示されます。
ルーターは、id
を使用して、正しいヒーローの詳細を表示します。
まず、ナビゲート元のコンポーネントで、次のメンバーをインポートします。
import { ActivatedRoute } from '@angular/router';import { Observable } from 'rxjs';import { switchMap } from 'rxjs/operators';
次に、アクティブなルートサービスを注入します。
constructor(private route: ActivatedRoute) {}
クラスを構成して、heroes$
というObservable、ヒーローの id
番号を保持する selectedId
、および ngOnInit()
内のヒーローを取得できるようにします。次のコードを追加して、選択したヒーローの id
を取得します。
このコードスニペットは、リスト、ヒーローサービス、ヒーローを取得する関数、およびリストと詳細をレンダリングするためのHTMLが、Tour of Heroesの例と同じようにあることを前提としています。
heroes$: Observable<Hero[]>;selectedId: number;heroes = HEROES;ngOnInit() { this.heroes$ = this.route.paramMap.pipe( switchMap(params => { this.selectedId = Number(params.get('id')); return this.service.getHeroes(); }) );}
次に、ナビゲート先のコンポーネントで、次のメンバーをインポートします。
import { Router, ActivatedRoute, ParamMap } from '@angular/router';import { Observable } from 'rxjs';
コンポーネントクラスのコンストラクターに ActivatedRoute
と Router
を注入して、このコンポーネントで使用できるようにします。
hero$: Observable<Hero>;constructor( private route: ActivatedRoute, private router: Router ) {}ngOnInit() { const heroId = this.route.snapshot.paramMap.get('id'); this.hero$ = this.service.getHero(heroId);}gotoItems(hero: Hero) { const heroId = hero ? hero.id : null; // Pass along the hero id if available // so that the HeroList component can select that item. this.router.navigate(['/heroes', { id: heroId }]);}
遅延読み込み
必要に応じてモジュールを遅延読み込みするようにルートを構成できます。つまり、アプリケーションが起動したときにすべてのモジュールを読み込むのではなく、必要に応じてモジュールを読み込みます。 さらに、アプリケーションの一部をバックグラウンドでプリロードして、ユーザー体験を向上させることができます。
遅延読み込みとプリロードの詳細については、専用のガイド 遅延読み込み を参照してください。
権限のないアクセスの防止
ルートガードを使用して、ユーザーが権限なしでアプリケーションの特定の部分にナビゲートできないようにします。 Angularでは、次のルートガードを使用できます。
ルートガードを使用するには、コンポーネントレスルート を使用することを検討してください。これにより、子ルートのガードが容易になります。
ガードのファイルを作成します。
ng generate guard your-guard
ガードファイルに、使用するガード関数を追加します。
次の例では、canActivateFn
を使用してルートをガードしています。
export const yourGuardFunction: CanActivateFn = ( next: ActivatedRouteSnapshot, state: RouterStateSnapshot) => { // your logic goes here }
ルーティングモジュールで、routes
構成の適切なプロパティを使用します。
ここでは、canActivate
は、ルーターに、この特定のルートへのナビゲーションを仲介するよう指示します。
{ path: '/your-path', component: YourComponent, canActivate: [yourGuardFunction],}
リンクパラメータ配列
リンクパラメータ配列には、ルーターナビゲーションの次の要素が含まれています。
- 宛先コンポーネントへのルートのパス
- ルートURLに含まれる、必須とオプションのルートパラメータ
次のように、RouterLink
ディレクティブをこのような配列にバインドします。
<a [routerLink]="['/heroes']">Heroes</a>
ルートパラメータを指定する場合は、次の2つの要素の配列になります。
<a [routerLink]="['/hero', hero.id]"> <span class="badge">{{ hero.id }}</span>{{ hero.name }}</a>
オプションのルートパラメータは、{ foo: 'foo' }
のようにオブジェクトで指定します。
<a [routerLink]="['/crisis-center', { foo: 'foo' }]">Crisis Center</a>
これらの3つの例は、ルーティングが1レベルのアプリケーションのニーズを満たしています。 ただし、危機センターなどの子ルーターを使用すると、新しいリンク配列の選択肢が生まれます。
次の最小限の RouterLink
の例は、危機センターの指定されたデフォルトの子ルートを基に構築されています。
<a [routerLink]="['/crisis-center']">Crisis Center</a>
次の点を確認してください。
- 配列の最初の項目は、親ルート (
/crisis-center
) を識別します - この親ルートのパラメータはありません
- 子ルートのデフォルトがないため、1つを選択する必要があります
CrisisListComponent
にナビゲートしており、そのルートパスは/
ですが、スラッシュを明示的に追加する必要はありません
危機センターのルートを排他的に使用して、AppComponent
テンプレートを再定義できます。
<a [routerLink]="['/crisis-center', 1]">Dragon Crisis</a>
- 配列の最初の項目は、親ルート (
/crisis-center
) を識別します - この親ルートのパラメータはありません
- 2番目の項目は、特定の危機に関する詳細の子ルートを識別します。
- 詳細の子ルートには
id
ルートパラメータが必要です。 - 配列の2番目の項目として、Dragon Crisisの
id
を追加しました。 - 結果のパスは
/crisis-center/1
です。
また、AppComponent
テンプレートを危機センターのルート専用に再定義できます:
@Component({ template: ` <h1 class="title">Angular Router</h1> <nav> <a [routerLink]="['/crisis-center']">Crisis Center</a> <a [routerLink]="['/crisis-center/1', { foo: 'foo' }]">Dragon Crisis</a> <a [routerLink]="['/crisis-center/2']">Shark Crisis</a> </nav> <router-outlet></router-outlet> `})export class AppComponent {}
要約すると、ルーティングが1レベル、2レベル、または複数レベルのアプリケーションを作成できます。 リンクパラメータ配列により、任意のルーティング深度、および任意の有効なルートパスのシーケンス、(必須) ルーターパラメータ、および (オプション) ルーターパラメータオブジェクトを表すことができます。
LocationStrategy
とブラウザ URL のスタイル
ルーターが新しいコンポーネントビューにナビゲートすると、ブラウザの場所と履歴が、そのビューのURLで更新されます。
最新のHTML5ブラウザは、history.pushState をサポートしています。これは、サーバーページのリクエストをトリガーせずに、ブラウザの場所と履歴を変更するテクニックです。 ルーターは、ページロードが必要な場合と区別できない「自然な」URLを作成できます。
この「HTML5 pushState」スタイルの危機センターのURLを示します。
localhost:3002/crisis-center
古いブラウザは、場所URLが変更された場合、変更が「#」(ハッシュ) の後に発生しない限り、サーバーにページリクエストを送信します。 ルーターは、この例外を利用して、ハッシュを含むアプリケーション内ルートURLを作成できます。 危機センターにルーティングする「ハッシュURL」を以下に示します。
localhost:3002/src/#/crisis-center
ルーターは、2つの LocationStrategy
プロバイダーで、両方のスタイルをサポートしています。
プロバイダー | 詳細 |
---|---|
PathLocationStrategy |
デフォルトの「HTML5 pushState」スタイル。 |
HashLocationStrategy |
「ハッシュ URL」スタイル。 |
RouterModule.forRoot()
関数は、LocationStrategy
を PathLocationStrategy
に設定します。これにより、デフォルトの戦略になります。
ブートストラッププロセス中にオーバーライドを使用して、HashLocationStrategy
に切り替えることもできます。
HELPFUL: プロバイダーとブートストラッププロセスの詳細については、依存性の注入 を参照してください。
ルーティング戦略の選択
プロジェクトの開発の早い段階でルーティング戦略を選択する必要があります。なぜなら、アプリケーションが本番環境になると、サイトの訪問者はアプリケーションのURLリファレンスを使用し、それに依存するからです。
ほとんどのAngularプロジェクトは、デフォルトのHTML5スタイルを使用する必要があります。 これは、ユーザーが理解しやすいURLを生成し、サーバーサイドレンダリングを行うオプションを保持します。
サーバーで重要なページをレンダリングすることは、アプリケーションが最初にロードされたときの、知覚される応答性を大幅に向上させる可能性のあるテクニックです。 そうでなければ、起動に10秒以上かかるアプリケーションは、サーバーでレンダリングされ、ユーザーのデバイスに1秒未満で配信される可能性があります。
このオプションは、アプリケーションのURLが、ハッシュ (#
) 文字を含まない通常のWeb URLに見える場合にのみ使用できます。
<base href>
ルーターは、ナビゲーションにブラウザの history.pushState を使用します。
pushState
を使用すると、アプリケーション内URLパスをカスタマイズできます。たとえば、localhost:4200/crisis-center
です。
アプリケーション内URLは、サーバー URLと区別がつかない場合があります。
最新のHTML5ブラウザは、pushState
を初めてサポートしたため、多くの人がこれらのURLを「HTML5スタイル」のURLと呼んでいます。
HELPFUL: HTML5スタイルのナビゲーションは、ルーターのデフォルトです。
LocationStrategy とブラウザ URL のスタイル セクションでは、HTML5スタイルが好ましい理由、その動作を調整する方法および必要に応じて古いハッシュ (#
) スタイルに切り替える方法について説明します。
pushState
ルーティングが機能するには、アプリケーションの index.html
に <base href>
要素 を追加する必要があります。
ブラウザは、<base href>
の値を使用して、CSSファイル、スクリプト、画像を参照するときに、相対URLにプレフィックスを付けます。
<head>
タグの直後に <base>
要素を追加します。
app
フォルダーがアプリケーションルートの場合、このアプリケーションの場合と同じように、index.html
の href
値を次のように設定します。
src/index.html (base-href)
<!DOCTYPE html><html lang="en"> <head> <!-- Set the base href --> <base href="/"> <title>Angular Router</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> </head> <body> <app-root></app-root> </body></html>
HTML5 URL と <base href>
次のガイドラインでは、URL の異なる部分について説明します。 この図は、これらの部分を示しています。
foo://example.com:8042/over/there?name=ferret#nose\_/ \______________/\_________/ \_________/ \__/ | | | | |scheme authority path query fragment
ルーターはデフォルトで HTML5 pushState スタイルを使用しますが、<base href>
でその戦略を構成する必要があります。
戦略を構成する推奨される方法は、index.html
の <head>
に <base href>
要素 タグを追加することです。
<base href="/">
このタグがないと、ブラウザはアプリケーションに「ディープリンク」するときに、リソース (画像、CSS、スクリプト) をロードできない場合があります。
一部の開発者は、<head>
または index.html
にアクセスできないため、<base>
要素を追加できない場合があります。
これらの開発者は、次の2つの手順を実行することで、HTML5 URLを引き続き使用できます。
ルーターに適切な
APP_BASE_HREF
値を提供します。すべてのWebリソース (CSS、画像、スクリプト、テンプレートHTMLファイル) に、ルートURL (権限を持つURL) を使用します。
<base href>
のpath
は、スラッシュで終わる必要があります。ブラウザは、右端の "/
" の後に続くpath
内の文字を無視します<base href>
にquery
部分が含まれている場合、query
は、ページのリンクのpath
が空でquery
がない場合にのみ使用されます。 つまり、<base href>
のquery
は、HashLocationStrategy
を使用する場合にのみ含まれます。ページのリンクがルートURL (権限を持つ) の場合、
<base href>
は使用されません。 このように、権限を持つAPP_BASE_HREF
は、Angularによって作成されるすべてのリンクが<base href>
値を無視するようにします。<base href>
のフラグメントは、決して 永続化されません
<base href>
がターゲットURIを作成するためにどのように使用されるかについての詳細については、RFC のリファレンスの変換に関するセクションを参照してください。
HashLocationStrategy
AppModule
の RouterModule.forRoot()
の2番目の引数に useHash: true
を提供することで、HashLocationStrategy
を使用します。
providers: [ provideRouter(appRoutes, withHashLocation())]
RouterModule.forRoot
を使用する場合、これは2番目の引数で useHash: true
を指定して構成されます。RouterModule.forRoot(routes, {useHash: true})
.