angular6+ 环境下 监控路由变化来设置title

1. 首先探讨下如何设置title

1. 显而易见的方法是把组件的属性绑定到 HTML 的 <title> 标签上,像这样:

<title>{{This_Does_Not_Work}}</title>

但是这样不行的,应用程序的根组件(<app></app>)是一个包含在 <body> 标签里的元素,该 HTML 的 <title> 在文档的 <head> 元素里,在 <body>(<app> 之外,Angular 的数据绑定无法访问到它。

2.  我们可以这样 document.title = 'my-title'。但是这样做不够优雅,并且document只是浏览器的元素,这样如果程序需要泡在其他环境下,那么就需要更改代码了。

3. 好在,Angular 在浏览器平台的包中,提供了一个Title服务,弥补了这种差异。Title服务是一个简单的类,提供了一个API,用来获取和设置当前HTML文档的标题。

  • getTitle(): string —— 获取当前 HTML 文档的标题。
  • setTitle( newTitle: string) —— 设置当前 HTML 文档的标题。
export class AppComponent {
  public constructor(private titleService: Title ) { }

  public setTitle( newTitle: string) {
    this.titleService.setTitle( newTitle );
  }
}

4. 这样以后就算程序不运行在浏览器环境中,只要替换Title这个依赖注入的服务就可以了,不需要更改业务代码。

2. 那么angular服务如何监控路由变化来动态设置title呢

如果每一个模块都写一遍setTitle是不是很累,那么该如何使用呢。

在 app.component.ts 中

import {Component, OnInit} from '@angular/core';
import {ActivatedRoute, NavigationEnd, Router} from '@angular/router';
import {Title} from '@angular/platform-browser';
import {filter, map} from 'rxjs/operators';

@Component({
    selector: 'app-root',
    templateUrl: 'app.component.html'
})
export class AppComponent implements OnInit {
    constructor(private router: Router,
                private title: Title) {
    }


    setTitle() {
        this.router.events
            .pipe(
                filter(event => event instanceof NavigationEnd),
                map(() => this.router)
            )
            .subscribe((event) => {

                // 更改页面title
                const titles = this.getTitle(this.router.routerState, this.router.routerState.root);
                const title = titles[titles.length - 1];
                if (title) {
                    this.title.setTitle(title);
                }
            });
    }

    getTitle(state, parent) {
        const data = [];
        if (parent && parent.snapshot.data && parent.snapshot.data.title) {
            data.push(parent.snapshot.data.title);
        }

        if (state && parent) {
            data.push(...this.getTitle(state, state.firstChild(parent)));
        }
        return data;
    }


    ngOnInit() {
        this.setTitle();
    }
}

在 app-routing.module.ts 中

import {NgModule} from '@angular/core';
import {PreloadAllModules, RouterModule, Routes} from '@angular/router';

// path: '**' 要放在最底下
const routes: Routes = [
    {path: '', loadChildren: './tabs/tabs.module#TabsPageModule', data: {title: '导航'}},
    {path: 'home', loadChildren: './home/home.module#HomePageModule', data: {title: '首页'}},
    {path: '**', loadChildren: './page-not-found/page-not-found.module#PageNotFoundPageModule', data: {title: '页面未找到'}},


];

@NgModule({
    imports: [
        RouterModule.forRoot(routes, {preloadingStrategy: PreloadAllModules})
    ],
    exports: [RouterModule]
})
export class AppRoutingModule {
}

 

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值