web-dev-qa-db-fra.com

comment changer le titre de la page dans le routeur angular2

J'essaie de changer le titre de la page depuis le routeur, est-ce possible?

import {RouteConfig} from 'angular2/router';
@RouteConfig([
  {path: '/home', component: HomeCmp, name: 'HomeCmp' }
])
class MyApp {}
53
B Hull

Le service Title @EricMartinez indique a une méthode setTitle() - c'est tout ce dont vous avez besoin pour définir le titre. 

Pour ce qui est de le faire automatiquement lors des changements de route, à partir de maintenant, il n'y a pas d'autre moyen intégré de le faire que de s'abonner à Router et d'appeler setTitle() dans votre rappel: 

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));
       });
    }
 }

Cela dit, j’insiste sur à partir de maintenant car le routeur fait encore l’objet d’un développement important et j’espère (ou du moins espérer) que nous pourrons le faire via RouteConfig dans la version finale.

MODIFIER:

Depuis la sortie de Angular 2 (2.0.0), quelques changements ont été apportés:

54
drewmoore

Voici mon approche qui fonctionne bien, en particulier pour les routes imbriquées:

J'utilise une méthode d'assistance récursive pour récupérer le titre disponible le plus profond après le changement d'un itinéraire:

@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;
  }
}

Cela suppose que vous avez attribué des titres de page à la propriété data de vos itinéraires, comme ceci:

{
  path: 'example',
  component: ExampleComponent,
  data: {
    title: 'Some Page'
  }
}
15
Martin Cremer

Pour Angular 4+:

Si vous souhaitez utiliser les données de route personnalisées pour définir le titre de la page pour chaque chemin de route, l'approche suivante fonctionnera pour les routes imbriquées et avec la version angulaire 4+:

Vous pouvez passer le titre de la page dans la définition de votre itinéraire:

  {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'}},

Maintenant, le plus important dans votre composant de niveau supérieur (c.-à-d. AppComponent), vous pouvez capturer globalement les données personnalisées de route à chaque changement de route et mettre à jour le titre de la page:

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);
       });
    }
 }

Le code ci-dessus est testé contre la version angulaire 4+.

12
asmmahmud

C'est vraiment très facile à faire, vous pouvez suivre les étapes suivantes pour voir les effets immédiats:

nous fournissons le service Title dans 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 { }

Puis importez ce service dans le composant souhaité:

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 );
  }
}

cliquez maintenant sur ces liens pour voir le titre changer.

vous pouvez aussi utiliser ng2-meta pour changer le titre et la description de la page, vous pouvez vous référer à ce lien

https://github.com/vinaygopinath/ng2-meta

8
Shailesh kala

Angular 2 fournit un Title Service see La réponse de Shailesh n’est que la copie de ce code.

Je notre app.module.ts

import { BrowserModule, Title } from '@angular/platform-browser';
........
providers: [..., Title],
bootstrap: [AppComponent]

Passons maintenant à notre 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 );
    }
}

Mettez la balise de titre sur votre composant html et il se lira et se configurera pour vous.

Si vous voulez savoir comment le définir dynamiquement et pour plus de détails, consultez cet article

5
Ali Adravi

C'est ce que je suis allé avec:

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;
}
2
John

Voici le moyen le plus simple de changer le titre de la page lorsque vous naviguez entre les pages/vues (testé à partir de Angular @ 2.3.1). Appliquez simplement la solution suivante à toutes les vues que vous avez et vous devriez être prêt à partir:

Exemple de code dans la page À propos de nous/view:

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');
  }

}

Exemple de code dans la page Contactez-nous/vue:

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

export class ContactusComponent implements OnInit {

  constructor(private _titleService: Title) {
  }

  ngOnInit() {
    //Set page Title
    this._titleService.setTitle('Contact Us');
  }

}
1
Devner

Dans l'exemple ci-dessous:

-Nous avons ajouté un objet de données: {title: 'NAME'} à n'importe quel objet de routage.

-Nous avons défini un nom de base ("CTM") pour le temps de téléchargement (lorsque vous cliquez sur F5 pour Refreash ..): <title>CTM</title>.

-Nous avons ajouté la classe "TitleService".

-Nous gérons les événements Routher en les filtrant depuis app.component.ts.

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);
        });

    }


}
1
Dudi

Angular 6+ J'ai modifié l'ancien code en utilisant new Pipe () et son fonctionnement correct.

import { Title } from '@angular/platform-browser';
import { filter, map, mergeMap } from 'rxjs/operators';

...

constructor(
    private router: Router,
    public activatedRoute: ActivatedRoute,
    public titleService: Title,
  ) {
    this.setTitle();
  }

....

setTitle() {
  this.router.events.pipe(
    filter((event) => event instanceof NavigationEnd),
    map(() => this.activatedRoute),
    map((route: any) => {
      while (route.firstChild) route = route.firstChild;
      return route;
    }),
    filter((route) => route.outlet === 'primary'),
    mergeMap((route: any) => route.data)).subscribe((event) => {
      this.titleService.setTitle(event['title']);
      console.log('Page Title', event['title']);
    })
  }
1
Suhel Khan
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');
   }
}
1
Yoav Schniederman

Angulaire 6+  

si la route est configurée comme suit: -

Routes = [
     {  path: 'dashboard',
       component: DashboardComponent,
       data: {title: 'Dashboard'}
   }]

** Puis dans le constructeur du composant, le titre peut être défini comme suit: - ** 

 constructor( private _titleService: Title, public activatedRoute: ActivatedRoute) {
    activatedRoute.data.pipe(map(data => data.title)).subscribe(x => this._titleService.setTitle(x));
   }
0
Ajitesh Sinha

Fonctionne très bien dans les angles 6 et 6+ avec la méthode Pipe and Map au lieu d'utiliser le filtre  

Etape 1 : configuration du routage

{path: 'dashboard', component: DashboardComponent, data: {title: 'My Dashboard'}},
{path: 'aboutUs', component: AboutUsComponent, data: {title: 'About Us'}},
{path: 'contactUs', component: ContactUsComponent, data: {title: 'Contact Us Page'}},

step2: dans votre module d'importation app.module.ts

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

puis dans fournisseur ajouter fournisseurs: [title]

Étape 3 Dans votre importation de composant principal  

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

constructor(private titleService: Title, private router: Router, private activatedRoute: ActivatedRoute) {

    }

ngOnInit() {

    this.router.events.pipe(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 => {
        this.titleService.setTitle(title);
    });

}
0
Mujahid

Je peux également recommander @ ngx-meta/core plugin que je viens de publier, dans le cas où vous cherchez une méthode pour définir le titre de la page et les balises méta de manière dynamique.

0
Burak Tasci