typescript - 如何在 angular2 路由中更改頁面標題
我正在嘗試從路由器更改頁面標題,這可以做到嗎?
import {RouteConfig} from 'angular2/router';
@RouteConfig([
{path: '/home', component: HomeCmp, name: 'HomeCmp' }
])
class MyApp {}
答案#1
EricMartinez 指出的 Title 服務有一個 setTitle() 方法——這就是你設置標題所需要的全部。
就自動在路由變更時執行而言,截至目前為止,除了訂閱 Router 並在回呼中調用 setTitle() 外,沒有內建的方法可以做到這一點:
import {RouteConfig} from 'angular2/router';
import {Title} from 'angular2/platform/browser';
@RouteConfig([
{path: '/home', component: HomeCmp, name: 'HomeCmp' }
])
class MyApp {
constructor(router:Router, title:Title) {
router.events.subscribe((event)=>{ //fires on every URL change
title.setTitle(getTitleFor(router.url));
});
}
}
話雖如此,我強調截至目前,因為這個路由器仍在密集開發中,我期望(或至少希望)我們最終能夠透過RouteConfig來實現這一點。
編輯:
自從 Angular 2(2.0.0) 發佈以來,有一些變化:
Title服務的文件現已在此處:https://angular.io/docs/ts/latest/api/platform-browser/index/Title-class.html- 該服務是從
'@angular/platform-browser'匯入的
答案#2
這是我的方法,效果很好,特別是對於巢狀路由:
我使用一個遞歸輔助方法來在路由改變後獲取最深層可用的標題:
@Component({
selector: 'app',
template: `
<h1>{{title | async}}</h1>
<router-outlet></router-outlet>
`
})
export class AppComponent {
constructor(private router: Router) {
this.title = this.router.events
.filter((event) => event instanceof NavigationEnd)
.map(() => this.getDeepestTitle(this.router.routerState.snapshot.root));
}
title: Observable<string>;
private getDeepestTitle(routeSnapshot: ActivatedRouteSnapshot) {
var title = routeSnapshot.data ? routeSnapshot.data['title'] : '';
if (routeSnapshot.firstChild) {
title = this.getDeepestTitle(routeSnapshot.firstChild) || title;
}
return title;
}
}
這是假設你已經在路由的 data 屬性中分配了頁面標題,像這樣:
{
path: 'example',
component: ExampleComponent,
data: {
title: 'Some Page'
}
}
答案#3
適用於 Angular 4+:
如果你想使用路由自訂資料來定義每個路由路徑的頁面標題,以下方法適用於巢狀路由並且 Angular 版本 4 以上:
你可以在路由定義中傳遞頁面標題:
{path: 'home', component: DashboardComponent, data: {title: 'Home Pag'}},
{path: 'about', component: AboutUsComponent, data: {title: 'About Us Page'}},
{path: 'contact', component: ContactUsComponent, data: {title: 'Contact Us Pag'}},
現在,最重要的是 在你的高階元件中(即 AppComponent),你可以在每次路由變更時全域捕捉路由自訂資料並更新頁面標題:
import {Title} from "@angular/platform-browser";
import { filter, map } from 'rxjs/operators';
export class AppComponent implements OnInit {
constructor(
private activatedRoute: ActivatedRoute,
private router: Router,
private titleService: Title
) { }
ngOnInit() {
this.router
.events.pipe(
filter(event => event instanceof NavigationEnd),
map(() => {
let child = this.activatedRoute.firstChild;
while (child) {
if (child.firstChild) {
child = child.firstChild;
} else if (child.snapshot.data && child.snapshot.data['title']) {
return child.snapshot.data['title'];
} else {
return null;
}
}
return null;
})).subscribe( (title: any) => {
this.titleService.setTitle(title);
});
}
上述程式碼已針對 Angular 版本 4 以上進行測試。
答案#4
這真的非常容易做到,你可以按照這些步驟來看到立即的效果:
我們在 Bootstrap 中提供標題服務:
import { NgModule } from '@angular/core';
import { BrowserModule, Title } from '@angular/platform-browser';
import { AppComponent } from './app.component';
@NgModule({
imports: [
BrowserModule
],
declarations: [
AppComponent
],
providers: [
Title
],
bootstrap: [ AppComponent ]
})
export class AppModule { }
然後在你想要的元件中匯入這個服務:
import { Component } from '@angular/core';
import { Title } from '@angular/platform-browser';
@Component({
selector: 'my-app',
template:
`<p>
Select a title to set on the current HTML document:
</p>
<ul>
<li><a (click)="setTitle( 'Good morning!' )">Good morning</a>.</li>
<li><a (click)="setTitle( 'Good afternoon!' )">Good afternoon</a>.</li>
<li><a (click)="setTitle( 'Good evening!' )">Good evening</a>.</li>
</ul>
`
})
export class AppComponent {
public constructor(private titleService: Title ) { }
public setTitle( newTitle: string) {
this.titleService.setTitle( newTitle );
}
}
現在點擊那些連結以查看標題變化。
你也可以使用 ng2-meta 來更改頁面標題和描述,你可以參考這個連結:
https://github.com/vinaygopinath/ng2-meta
