Angular にて、現在のルーティングに一致する際に class を付与する routerLinkActive
ディレクティブがあります。
これは、routerLink
とセットで利用することで、routerLink
に指定したルーティングが Active のときに、その要素に class を付与することができます。
基本的な使い方
以下 3 つのルーティングが定義されており、ナビゲーションで画面遷移をすることとします。
const routes: Routes = [
{ path: 'page1', component: Page1Component },
{ path: 'page2', component: Page2Component },
{ path: 'page3', component: Page3Component },
]
<ul>
<li><a [routerLink]="['page1']">Page 1 へ</a></li>
<li><a [routerLink]="['page2']">Page 2 へ</a></li>
<li><a [routerLink]="['page3']">Page 3 へ</a></li>
</ul>
このナビゲーションの <a>
要素に、現在表示中のページの場合に active
クラスを追加したい場合、routerLinkActive
ディレクティブを使って以下のように書くことができます。
<ul>
<li><a [routerLink]="['page1']" routerLinkActive="active">Page 1 へ</a></li>
<li><a [routerLink]="['page2']" routerLinkActive="active">Page 2 へ</a></li>
<li><a [routerLink]="['page3']" routerLinkActive="active">Page 3 へ</a></li>
</ul>
もし複数クラスを指定したい場合は、routerLinkActive="aaa bbb ccc"
と書くことができます。
別の要素にクラスを指定したい場合
例えば Bootstrap を利用する場合、<a>
要素ではなく親の <li>
要素にクラスを付与する必要があります。
その場合の対応方法は 2 通りあります。
-
<li>
要素にrouterLink
を移す - テンプレート参照変数 (Template Reference Variables) を利用する
方法 1 については特に説明も不要だと思いますので、ここでは方法 2 について説明します。
まず、routerLinkActive
ディレクティブをテンプレート参照変数に代入します。
<ul>
<li><a [routerLink]="['page1']" routerLinkActive #page1="routerLinkActive">Page 1 へ</a></li>
<li><a [routerLink]="['page2']" routerLinkActive #page2="routerLinkActive">Page 2 へ</a></li>
<li><a [routerLink]="['page3']" routerLinkActive #page3="routerLinkActive">Page 3 へ</a></li>
</ul>
ここでのポイントは 3 つです。
-
routerLinkActive
ディレクティブは省略できません。 - 上記例の
#page1
には、#
+ 任意の名前が指定できます。
(これがテンプレート参照変数です) -
#page1
以降の="routerLinkActive"
は省略できません。
ここまでで、#
以降に指定した名前で routerLinkActive
ディレクティブを参照できるようになりました。
routerLinkActive
ディレクティブには isActive
プロパティが定義されており、現在のルートが routerLink
で指定したルートと同じ場合に true
が返ってきます。
これを利用して、最後に <li>
属性にクラス active
を付与するように変更して完成です。
<ul>
<li [class.active]="page1.isActive"><a [routerLink]="['page1']" routerLinkActive #page1="routerLinkActive">Page 1 へ</a></li>
<li [class.active]="page2.isActive"><a [routerLink]="['page2']" routerLinkActive #page2="routerLinkActive">Page 2 へ</a></li>
<li [class.active]="page3.isActive"><a [routerLink]="['page3']" routerLinkActive #page3="routerLinkActive">Page 3 へ</a></li>
</ul>
まとめ
テンプレート内が少し複雑になってしまいましたが、TypeScript 側に 1 行も書かずにクラスの切り替えが実装できました。
少し調べると、TypeScript 側に Router
を DI して判定する方法などもありますが、テンプレート HTML で完結するので私はこの方法を採用しています。
同じような実装をする場合に、参考にしてみてください。
参考リンク
- RouterLinkActive - ts - API
https://angular.io/docs/ts/latest/api/router/index/RouterLinkActive-directive.html