如何在Angular应用程序中使用路由更改页面标题?

时间:2017-12-20 07:02:28

标签: angular angular5

是否有任何npm模块/其他方式如React-Helmet允许我们在浏览Angular应用程序时更改页面标题?

PS:我正在使用Angular 5.

9 个答案:

答案 0 :(得分:13)

您在Angular中有一个TitleService 5.在组件的构造函数中注入它,并使用setTitle()方法。

import {Title} from "@angular/platform-browser";

....

constructor(private titleService:Title) {
  this.titleService.setTitle("Some title");
}

以下是Angular的文档:https://v2.angular.io/docs/ts/latest/cookbook/set-document-title.html

答案 1 :(得分:4)

这是正确的使用方式

export class AppComponent implements OnInit {
  constructor(private router: Router, private titleService: Title) {
  }

  ngOnInit() {
    this.router.events
      .filter((event) => event instanceof NavigationEnd)
      .map(() => this.router)
      .subscribe((event) => {
          const title = this.getTitle(this.router.routerState, this.router.routerState.root).join(' | ');
          this.titleService.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;
  }


}

答案 2 :(得分:1)

这里已经过测试在Angular 8上设置页面标题的方式,但是您也可以在Angular 5上使用它。 设置完之后,您只需要在路由文件上设置标题,所有设置都会自动设置。

import { Component } from '@angular/core';
import { ActivatedRoute, Router, NavigationEnd } 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 {

    constructor (private router: Router, private activatedRoute:    ActivatedRoute, private titleService: Title) {
        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( (data: any) => {
            if (data) {
                this.titleService.setTitle(data + ' - Website Name');
            }
        });
    }

}

在路由文件上,您可以执行以下操作:

const routes: Routes = [
    {
        path: 'dashboard',
        component: DefaultDashboardComponent,
        data: {
            title: 'Dashboard'
        }
    }
];

答案 3 :(得分:1)

要制作动态更改的标题,我们可以使用角度模块@angular/platform-browser,并使用功能setTitle设置标题。

有关更多详细信息,请检查:platform-browser

答案 4 :(得分:0)

我宁愿添加包装器类,以确保如果从“ @ angular / platform-b​​rowser”中导入{Title}; 在即将发布的版本中进行更改,我不会在任何地方更改:) ...也许叫做“ AppTitleService”

import { Injectable } from '@angular/core';
import { Title } from '@angular/platform-browser';

@Injectable({ providedIn: 'root' })
export class AppTitleService {

    constructor(private titleService: Title) { }

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

答案 5 :(得分:0)

您可以在下面执行 app.component.html

<div class="content">
  <h1>Set Title in Angular of Website</h1>
  <a  (click) ="setTitleHome()">Home</a>
  <a  (click) ="setTitleLogin()">Login</a>
  <a  (click) ="setTitleRegister()">Register</a>
</div>

更改app.component.ts文件中的标题后

constructor(private serviceTitle: Title, private router:Router){

  }
  setTitleHome(){
    this.serviceTitle.setTitle("Home");
    this.router.navigateByUrl("/home");
  }
  setTitleLogin(){
    this.serviceTitle.setTitle("Login" +" | " +this.title);
    this.router.navigateByUrl("/login");
  }
  setTitleRegister(){
    this.serviceTitle.setTitle("Register" +" | " +this.title);
    this.router.navigateByUrl("/register");
  }

这是参考链接:https://code-android-example.blogspot.com/2019/08/how-to-set-title-in-angular-of-website.html

答案 6 :(得分:0)

我只是用这个

import { Title } from '@angular/platform-browser';
...

constructor(private title: Title){}

ngOnInit() {
 this.title.setTitle('title here');
}

答案 7 :(得分:0)

// Component.ts
    
    import { Component, OnInit } from '@angular/core';
    import { Router, NavigationEnd, ActivatedRoute } from '@angular/router';
    import { filter } from 'rxjs/operators';
    
    @Component({
      selector: 'app-component',
      templateUrl: './component.html',
      styleUrls: ['./component.css']
    })
    export class Component implements OnInit {
    
      constructor(private router: Router, private route: ActivatedRoute) { }
    
      path: string[] = [];
      pathTitle: string;
    
      ngOnInit() {
        this.router.events.pipe(
          filter(event => event instanceof NavigationEnd)
        ).subscribe((event: NavigationEnd) => {
            this.path = event.url.substring(1).split('/');  //  URL => stackOverflow
            this.pathTitle = this.route.root.firstChild.snapshot.data.title; // data.title => stack Overflow
        });
      }
    
    // app-routing.module.ts
    const routes: Routes = [
      { 
        path: 'stackOverflow', 
        component: Component, 
        data: {title: 'stack Overflow'}
       }
    ];

答案 8 :(得分:-1)

这是一个非递归解决方案,它也修复了在无路径或无组件嵌套路由的情况下的标题复制。

确保将 Angular 的 Title 服务添加到您的应用程序:https://angular.io/guide/set-document-title

然后在您的 app.component.ts

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

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {

  constructor(
    private readonly router: Router,
    private readonly titleService: Title
  ) { }

  ngOnInit() {
    this.router.events.pipe(
      filter((event) => event instanceof NavigationEnd)
    ).subscribe(() => {
      this.titleService.setTitle(this.getNestedRouteTitles().join(' | '));
    });
  }

  getNestedRouteTitles(): string[] {
    let currentRoute = this.router.routerState.root.firstChild;
    const titles: string[] = [];

    while (currentRoute) {
      if (currentRoute.snapshot.routeConfig.data?.title) {
        titles.push(currentRoute.snapshot.routeConfig.data.title);
      }

      currentRoute = currentRoute.firstChild;
    }

    return titles;
  }

  getLastRouteTitle(): string {
    let currentRoute = this.router.routerState.root.firstChild;

    while (currentRoute.firstChild) {
      currentRoute = currentRoute.firstChild;
    }

    return currentRoute.snapshot.data?.title;
  }
}

访问特定的 routeConfig.data 可防止重复继承的 title 属性。

main-routing.module.ts 或任何其他路由文件中:

const routes: Routes = [
  {
    path: '',
    component: MainComponent,
    data: { title: 'MyApplication' },
    children: [
      {
        path: '',
        canActivateChild: [AuthGuard],
        children: [
          {
            path: 'dashboard',
            loadChildren: () => import('../dashboard/dashboard.module').then(m => m.DashboardModule),
            data: { title: 'Dashboard' }
          },
          {
            path: 'settings',
            loadChildren: () => import('../settings/settings.module').then(m => m.SettingsModule),
            data: { title: 'Settings' }
          }
        ]
      }
    ]
  }
];