如何更改angular2路由器中的页面标题
我正在尝试从路由器更改页面标题,可以这样做吗?
import {RouteConfig} from 'angular2/router'; @RouteConfig([ {path: '/home', component: HomeCmp, name: 'HomeCmp' } ]) class MyApp {}
Title
服务@EricMartinez指出有一个setTitle()
方法 – 这就是所有你需要设置标题。
就在路由更改中自动执行而言, 截至目前 ,除了订阅Router
并在您的callback中调用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)); }); } }
这就是说,我现在强调的是,因为路由器还处于重大的发展阶段,我期望(或者至less是希望)能够在最终版本中通过RouteConfig
来做到这一点。
编辑:
至于Angular 2(2.0.0)的发布,有几件事情已经发生了变化:
-
Title
服务的文档现在在这里: https : //angular.io/docs/ts/latest/api/platform-browser/index/Title-class.html - 该服务从
'@angular/platform-browser'
导入
这是我的方法,工作正常,尤其是嵌套路线:
我使用recursion辅助方法来获取路由更改后最深的可用标题:
@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' } }
这样做非常容易,你可以按照下面的步骤来看看即时的效果:
我们在bootstrap中提供Title服务:
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来改变页面标题和描述,你可以参考这个链接:
Angular 2提供了一个标题服务,请参阅Shailesh答案只是该代码的副本。
我们的app.module.ts
import { BrowserModule, Title } from '@angular/platform-browser'; ........ providers: [..., Title], bootstrap: [AppComponent]
现在转到我们的app.component.ts
import { Title } from '@angular/platform-browser'; ...... export class AppComponent { public constructor(private titleService: Title ) { } public setTitle( newTitle: string) { this.titleService.setTitle( newTitle ); } }
把标题标签放在你的组件html上,它会为你读取和设置。
如果你想知道如何dynamic设置它, 进一步的细节见这篇文章
这是我一起去的:
constructor(private router: Router, private title: Title) { } ngOnInit() { this.router.events.subscribe(event => { if (event instanceof NavigationEnd) { this.title.setTitle(this.recursivelyGenerateTitle(this.router.routerState.snapshot.root).join(' - ')); } }); } recursivelyGenerateTitle(snapshot: ActivatedRouteSnapshot) { var titleParts = <string[]>[]; if (snapshot) { if (snapshot.firstChild) { titleParts = titleParts.concat(this.recursivelyGenerateTitle(snapshot.firstChild)); } if (snapshot.data['title']) { titleParts.push(snapshot.data['title']); } } return titleParts; }
import {Title} from "@angular/platform-browser"; @Component({ selector: 'app', templateUrl: './app.component.html', providers : [Title] }) export class AppComponent implements { constructor( private title: Title) { this.title.setTitle('page title changed'); } }
在下面的例子中:
– 我们向任何路由对象添加了数据对象{title:'NAME'}。
– 我们为上传时间设置一个基本名称(“CTM”)(点击F5进行Refreash ..): <title>CTM</title>
。
– 我们添加了“TitleService”类。
我们通过从app.component.ts中过滤来处理Routher事件。
index.html的:
<!DOCTYPE html> <html> <head> <base href="/"> <title>CTM</title> </head>
…
app.module.ts:
import { NgModule, enableProdMode } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { TitleService } from './shared/title.service'; ... @NgModule({ imports: [ BrowserModule, .. ], declarations: [ AppComponent, ... ], providers: [ TitleService, ... ], bootstrap: [AppComponent], }) export class AppModule { } enableProdMode();
title.service.ts:
import { Injectable } from '@angular/core'; import { Title } from '@angular/platform-browser'; import { ActivatedRouteSnapshot } from '@angular/router'; @Injectable() export class TitleService extends Title { constructor() { super(); } private recursivelyGenerateTitle(snapshot: ActivatedRouteSnapshot) { var titleParts = <string[]>[]; if (snapshot) { if (snapshot.firstChild) { titleParts = this.recursivelyGenerateTitle(snapshot.firstChild); } if (snapshot.data['title']) { titleParts.push(snapshot.data['title']); } } return titleParts; } public CTMGenerateTitle(snapshot: ActivatedRouteSnapshot) { this.setTitle("CTM | " + this.recursivelyGenerateTitle(snapshot).join(' - ')); } }
APP-routing.module.ts:
import { Injectable } from '@angular/core'; import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; import { MainComponent } from './components/main.component'; import { Router, CanActivate } from '@angular/router'; import { AuthGuard } from './shared/auth/auth-guard.service'; import { AuthService } from './shared/auth/auth.service'; export const routes: Routes = [ { path: 'dashboard', component: MainComponent, canActivate: [AuthGuard], data: { title: 'Main' } }, ]; @NgModule({ imports: [ RouterModule.forRoot(routes, { useHash: true }) // .../#/crisis-center/ ], exports: [RouterModule], providers: [ .. ] }) export class AppRoutingModule { } export const componentsOfAppRoutingModule = [MainComponent];
app.component.ts:
import { Component } from '@angular/core'; import { Router, NavigationEnd, ActivatedRouteSnapshot } from '@angular/router'; import { TitleService } from './shared/title.service'; @Component({ selector: 'ctm-app', template: ` <!--<a [routerLink]="['/dashboard']">Dashboard</a> <a [routerLink]="['/login']">Login</a> <a [routerLink]="['/']">Rooting</a>--> <router-outlet></router-outlet> ` }) export class AppComponent { constructor(private router: Router, private titleService: TitleService) { this.router.events.filter((event) => event instanceof NavigationEnd).subscribe((event) => { console.log("AppComponent.constructor: Setting HTML document's Title"); this.titleService.CTMGenerateTitle(this.router.routerState.snapshot.root); }); } }
对于Angular 4+:
如果要使用路由自定义数据为每个pathpath定义页面标题,则以下方法适用于嵌套路由,并且使用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"; export class AppComponent implements OnInit { constructor( private activatedRoute: ActivatedRoute, private router: Router, private titleService: Title ) { } ngOnInit() { this.router .events .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+进行testing的。
我还可以推荐我刚刚发布的@ ngx-meta / core插件插件,如果你正在寻找一种方法来dynamic地设置页面标题和元标签。
当浏览页面/视图(从Angular @ 2.3.1开始testing)时,以下是更改页面标题的最简单方法。 只需将以下解决scheme应用到您拥有的所有视图中,您就可以顺利完成任务:
关于我们页面/视图中的示例代码:
import {Title} from "@angular/platform-browser"; export class AboutUsComponent implements OnInit { constructor(private _titleService: Title) { } ngOnInit() { //Set page Title when this view is initialized this._titleService.setTitle('About Us'); } }
联系我们页面/视图中的示例代码:
import {Title} from "@angular/platform-browser"; export class ContactusComponent implements OnInit { constructor(private _titleService: Title) { } ngOnInit() { //Set page Title this._titleService.setTitle('Contact Us'); } }