Ich versuche, den Seitentitel vom Router aus zu ändern. Kann dies geschehen?
import {RouteConfig} from 'angular2/router';
@RouteConfig([
{path: '/home', component: HomeCmp, name: 'HomeCmp' }
])
class MyApp {}
Der Title
-Dienst @EricMartinez weist darauf hin hat eine setTitle()
-Methode - das ist alles, was Sie brauchen, um den Titel festzulegen.
Im Hinblick auf das automatische Ausführen von Routenänderungen ist ab sofort keine andere Möglichkeit, dies zu tun, als Router
zu abonnieren und setTitle()
in Ihrem Rückruf aufzurufen:
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));
});
}
}
Das heißt, ich unterstreiche ab sofort, da sich der Router noch in der Entwicklung befindet und ich erwarte (oder hoffe zumindest), dass wir dies in der endgültigen Version über RouteConfig
tun können.
BEARBEITEN:
Seit der Veröffentlichung von Angular 2 (2.0.0) haben sich einige Dinge geändert:
Title
-Dienst sind jetzt hier: https://angular.io/docs/ts/latest/api/platform-browser/index/Title-class.html'@angular/platform-browser'
importiert.Hier ist mein Ansatz, der vor allem für verschachtelte Routen gut funktioniert:
Ich verwende eine rekursive Hilfsmethode, um den tiefsten verfügbaren Titel zu holen, nachdem sich eine Route geändert hat:
@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;
}
}
Dies setzt voraus, dass Sie den Datentiteln Ihrer Routen Seitentitel wie folgt zugewiesen haben:
{
path: 'example',
component: ExampleComponent,
data: {
title: 'Some Page'
}
}
Für Angular 4+:
Wenn Sie benutzerdefinierte Streckendaten verwenden möchten, um den Seitentitel für jeden Routenpfad zu definieren, funktioniert der folgende Ansatz für die verschachtelten Routen und mit der Winkelversion 4+:
Sie können den Seitentitel in Ihrer Routendefinition übergeben:
{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'}},
Nun, am wichtigsten in Ihrer übergeordneten Komponente (z. B. AppComponent
) können Sie die benutzerdefinierten Routendaten bei jeder Routenänderung global abfangen und den Seitentitel aktualisieren:
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);
});
}
}
Der obige Code wird gegen die Winkelversion 4+ getestet.
Es ist wirklich sehr einfach, dies zu tun. Sie können den umgekehrten Schritten folgen, um die unmittelbaren Auswirkungen zu sehen:
wir bieten den Title-Dienst in Bootstrap an:
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 { }
Importieren Sie dann diesen Service in die gewünschte Komponente:
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 );
}
}
klicken Sie jetzt auf diese Links, um den Titel zu ändern.
sie können ng2-meta auch verwenden, um den Seitentitel und die Beschreibung zu ändern. Sie können auf diesen Link verweisen:
Angular 2 bietet einen Title Service siehe Shailesh-Antwort ist nur eine Kopie dieses Codes.
Ich habe unsere app.module.ts
import { BrowserModule, Title } from '@angular/platform-browser';
........
providers: [..., Title],
bootstrap: [AppComponent]
Gehen Sie jetzt zu 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 );
}
}
Fügen Sie das Titel-Tag in Ihre Komponenten-HTML ein und es wird für Sie gelesen und festgelegt.
Wenn Sie wissen möchten, wie Sie es dynamisch einstellen und weitere Details finden Sie in diesem Artikel
Das ist was ich ging mit:
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;
}
Der einfachste Weg, um den Titel der Seite zu ändern, wenn Seiten/Ansichten navigiert werden (getestet ab Angular @ 2.3.1) Wenden Sie einfach die folgende Lösung auf alle Ansichten an, die Sie haben, und Sie sollten gut sein:
Beispielcode in der Seite Über uns/Ansicht:
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');
}
}
Beispielcode in der Kontaktseite/Ansicht:
import {Title} from "@angular/platform-browser";
export class ContactusComponent implements OnInit {
constructor(private _titleService: Title) {
}
ngOnInit() {
//Set page Title
this._titleService.setTitle('Contact Us');
}
}
Im folgenden Beispiel:
- Wir haben ein Objekt der Daten: {title: 'NAME'} zu einem Routing-Objekt hinzugefügt.
- Wir haben einen grundlegenden Namen ("CTM") für die Uploadzeit festgelegt (wenn Sie auf F5 für Refreash .. klicken): <title>CTM</title>
.
- Wir haben die "TitleService" -Klasse hinzugefügt.
-wir behandeln Routher-Ereignisse durch Filtern aus 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);
});
}
}
Angular 6+ Ich habe den alten Code mit neuem Pipe () geändert und funktioniert einwandfrei.
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']);
})
}
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');
}
}
Winkel 6+
wenn die Route wie folgt konfiguriert ist: -
Routes = [
{ path: 'dashboard',
component: DashboardComponent,
data: {title: 'Dashboard'}
}]
** Dann kann der Komponententitel wie folgt festgelegt werden: - **
constructor( private _titleService: Title, public activatedRoute: ActivatedRoute) {
activatedRoute.data.pipe(map(data => data.title)).subscribe(x => this._titleService.setTitle(x));
}
Feinarbeiten in Winkel 6 und 6+ mit Pipe- und Map-Methode anstelle von filter
Step1: Routing-Setup
{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: in Ihrem Importmodul für app.module.ts
import { BrowserModule, Title } from '@angular/platform-browser';
dann im Provider Anbieter hinzufügen: [title]
Schritt 3In Ihrem Hauptkomponentenimport
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);
});
}
Ich kann auch @ ngx-meta/core plugin plugin empfehlen, das ich gerade veröffentlicht habe, in dem Fall, wenn Sie nach einer Methode suchen, um Seitentitel und Metatags dynamisch festzulegen.