経緯
- Angular2を練習していて、ページタイトルをパスに対応するものに変更することに成功したのでメモ。
- 単純な単一階層パスのみ対応。
- angular2/2.0.0-beta.1
- bootstrap/4.0.0-alpha.2
TS
app.component.ts
import {
Component,
provide
} from 'angular2/core';
import {
ROUTER_DIRECTIVES,
ROUTER_PROVIDERS,
Router,
RouteConfig,
Location,
LocationStrategy,
HashLocationStrategy
} from 'angular2/router';
import { Title } from 'angular2/platform/browser';
import { FaqComponent } from './faq/faq.component';
import { TestimonialComponent } from './testimonial/testimonial.component';
import { HomeComponent } from './home/home.component';
// Defines the AppComponent, which is the root component.
@Component({
selector: 'app',
templateUrl: 'app/app.component.html',
styleUrls: [ 'app/app.component.css' ],
directives: [ ROUTER_DIRECTIVES ],
providers: [ ROUTER_PROVIDERS,
provide( LocationStrategy, { useClass: HashLocationStrategy }),
Title
]
})
@RouteConfig([
{ path: '/home', name: 'Home', component: HomeComponent, useAsDefault: true },
{ path: '/testimonial', name: 'Testimonial', component: TestimonialComponent },
{ path: '/faq', name: 'Faq', component: FaqComponent }
])
export class AppComponent {
// 選択されているページを覚えておくための変数。
private selectedId: string;
// ページ名の配列をつくる。
private pageIds: string[] = [ "Home", "Testimonial", "Faq" ];
// 必要あれば、ベースのタイトルを用意する。
private baseTitle: string = "The Official Ninja Webpage";
// ページタイトルのハッシュを用意する。
private pageTitles: Object = {
home: "Home | " + this.baseTitle,
testimonial: "Testimonial | " + this.baseTitle,
faq: "Faq | " + this.baseTitle
};
// 依存性注入する。
constructor( private location: Location,
private title: Title,
private router: Router ) {
// パスが切り替わった時に毎回実施する処理。
// これにより、戻るボタンが押された時にも対応可能。
router.subscribe( ( path ) => {
this.setSelected( path );
});
}
// 現在のパスを検知し、バスからスラッシュを取り除いたものをIDとして覚えておく。
// パスが空文字列であれば、デフォルトのページをセットする。
ngOnInit() {
// 現在のパスを検知。
let path = this._location.path();
// バスからスラッシュを取り除いたものをIDとして覚えておく。
// パスが空文字列であれば、デフォルトのものをIDとする。
let id = ( path.length < 1 ) ? "home" : path.substring( 1 );
// 上記IDを選択されている状態にセットする。
this.setSelected( id );
}
/**
* 渡されたIDが現在選択されているページのものであればtrue。
* 大文字小文字は区別しない。
*/
private isSelected( id: string ) {
return this.selectedId.toLowerCase() === id.toLowerCase();
}
/**
* 指定のページを選択されている状態にし、ページタイトルをパスに対応するものに変更する。
* 小文字に統一。
*/
private setSelected( id: string ) {
// selectedIdを更新。小文字に統一。
this.selectedId = id.toLowerCase();
// ページタイトルを更新。
let title = this.pageTitles[ this.selectedId ];
this.title.setTitle( title );
}
}
HTML
app.component.html
<header>
<nav class="navbar navbar-dark bg-inverse">
<div class="container">
<!-- Logo -->
<a
[routerLink]="['Home']"
id="logo"
class="navbar-brand" >
<!-- HTML Unicode for Ninja in Kanji -->
忍
者
</a>
<!-- Navigation links -->
<ul class="nav navbar-nav">
<li *ngFor="#page of pageIds"
class="nav-item"
[class.active]="isSelected( page )" >
<a
[routerLink]="[page]"
class="nav-link">
{{ page }}
</a>
</li>
</ul>
</div>
</nav>
</header>
<!-- Page content -->
<div class="page container">
<router-outlet></router-outlet>
</div>
<hr class="m-y-2">
<footer>...</footer>