我已经定义了许多路线如下:
export const AppRoutes: Routes = [
{path: '', component: HomeComponent, data: {titleKey: 'homeTitle'}},
{path: 'signup', component: SignupComponent, data: {titleKey: 'SIGNUP_FORM.TITLE'}},
{path: 'signin', component: SigninComponent, data: {titleKey: 'SIGNIN_FORM.TITLE'}},
{path: 'sendpasswordresetinformation', component: SendPasswordResetInformationComponent},
{path: 'password/reset/:userAccountToken', component: PasswordResetComponent},
{
path: 'dashboard', component: DashboardComponent, children: [
{path: '', component: DashboardSummaryComponent},
{
path: 'message', children: [
{path: '', component: MessageSummaryComponent, data: {titleKey: 'MESSAGE_LIST.TITLE'}},
{path: 'conversation/:otherId', component: MessageConversationComponent, data: {titleKey: 'XXX'}}]
},
{
path: 'useraccount', component: UserAccountComponent, children: [
{
path: '',
component: UserAccountSummaryComponent,
data: {titleKey: 'XXX'},
resolve: {
userAccount: UserAccountResolve
}
},
{path: 'address', component: UserAccountAddressComponent, data: {titleKey: 'ADDRESS_FORM.TITLE'}},
{path: 'email', component: UserAccountEmailComponent, data: {titleKey: 'EMAIL_FORM.TITLE'}},
{
path: 'emailnotification',
component: UserAccountEmailNotificationComponent,
data: {titleKey: 'EMAIL_NOTIFICATION_FORM.TITLE'}
},
{path: 'firstname', component: UserAccountFirstNameComponent, data: {titleKey: 'FIRST_NAME_FORM.TITLE'}},
{path: 'password', component: UserAccountPasswordComponent, data: {titleKey: 'PASSWORD_FORM.TITLE'}}]
}]
}];
有些路线是其他路线的孩子。
我想找到一种方法来检索titleKey
上的data
属性,无论该路线是顶级路线还是另一条路线的孩子。
以下是我的尝试:
export class AppComponent implements OnInit {
constructor(private translate: TranslateService,
private sessionService: SessionService,
private titleService: Title,
private activatedRoute: ActivatedRoute) {
let userLang = 'fr';
translate.use(userLang);
moment.locale(userLang);
}
ngOnInit() {
this.sessionService.reloadPersonalInfo();
}
setTitle($event) {
this.translate.get(this.activatedRoute.snapshot.data['titleKey'])
.subscribe(translation=>this.titleService.setTitle(translation));
}
}
this.activatedRoute.snapshot.data['titleKey']
是undefined
。
有人可以建议如何在路线data
上检索物业,而不管路线的嵌套程度如何?
修改:在阅读官方angular documentation about ActivatedRoute后,我尝试在map
实例的数据属性上使用ActivatedRoute
运算符,如下所示:
@Component({
selector: 'app',
template: `
<section class="container-fluid row Conteneur">
<appNavbar></appNavbar>
<section class="container">
<router-outlet (activate)="setTitle($event)"></router-outlet>
</section>
</section>
<section class="container-fluid">
<appFooter></appFooter>
</section>
`,
directives: [NavbarComponent, FooterComponent, SigninComponent, HomeComponent, ROUTER_DIRECTIVES]
})
export class AppComponent implements OnInit {
constructor(private translate: TranslateService,
private sessionService: SessionService,
private titleService: Title,
private activatedRoute: ActivatedRoute) {
let userLang = 'fr';
translate.use(userLang);
moment.locale(userLang);
}
ngOnInit() {
this.sessionService.reloadPersonalInfo();
}
setTitle($event) {
this.activatedRoute.data.map(data=>data['titleKey'])
.do(key=>console.log(key))
.switchMap(key=>this.translate.get(key))
.subscribe(translation=>this.titleService.setTitle(translation));
}
}
然而key
总是未定义......
答案 0 :(得分:6)
我偶然发现了一个包含干净解决方案的精彩教程:https://toddmotto.com/dynamic-page-titles-angular-2-router-events。
以下是我最终使用上述教程中的解决方案并使用ng2 translate service将我的路由数据中指定的titleKeys
转换为正确的标签:
@Component({
selector: 'app',
encapsulation: ViewEncapsulation.None,
styleUrls: ['../styles/bootstrap.scss'],
template: `<section class="container-fluid row Conteneur">
<app-navbar></app-navbar>
<section class="container">
<router-outlet></router-outlet>
</section>
</section>
<section class="container-fluid">
<app-footer></app-footer>
</section>`
})
export class AppComponent implements OnInit {
constructor(private translate: TranslateService,
private sessionSigninService: SessionSigninService,
private titleService: Title,
private router: Router,
private activatedRoute: ActivatedRoute) {
let userLang = 'fr';
translate.use(userLang);
moment.locale(userLang);
}
ngOnInit() {
this.router.events
.filter(event => event instanceof NavigationEnd)
.map(() => this.activatedRoute)
.map(route => {
while (route.firstChild) route = route.firstChild;
return route;
})
.filter(route => route.outlet === 'primary')
.mergeMap(route => route.data)
.mergeMap(data => this.translate.get(data['titleKey']))
.subscribe(translation => this.titleService.setTitle(translation));
}
}
答案 1 :(得分:4)
我们遇到了同样的问题。我们决定以另一种方式去做。我们不是试图监听ActivatedRoute上的数据发出,而是在路由器本身上订阅events
Observable:
import { Component } from "@angular/core";
import { NavigationEnd, Router } from "@angular/router";
declare var module: any;
@Component({
moduleId: module.id,
selector: "app-layout",
templateUrl: "main-layout.component.html"
})
export class LayoutComponent {
titleKey: string;
constructor(private router: Router){}
ngOnInit() {
this.router.events
.filter((event: any) => event instanceof NavigationEnd)
.subscribe(() => {
var root = this.router.routerState.snapshot.root;
while (root) {
if (root.children && root.children.length) {
root = root.children[0];
} else if (root.data && root.data["titleKey"]) {
this.titleKey = root.data["titleKey"];
return;
} else {
return;
}
}
});
}
}
请注意,我们正在使用顶层使用的组件中的值,但需要来自最深子路径的数据。只要titleKey
更改值,您就可以非常轻松地将其转换为发出事件的服务。
希望这有帮助。
答案 2 :(得分:1)
<强>更新强>
您可以在AppComponent
,
constructor(private translate: TranslateService,
private sessionService: SessionService,
private titleService: Title,
private activatedRoute: ActivatedRoute) {
this.router.events.subscribe((arg) => {
if(arg instanceof NavigationEnd) {
console.log(this.getTitle(this.activatedRoute.snapshot));
}
});
}
getTitle = (snapshot) => {
if(!!snapshot && !!snapshot.children && !!snapshot.children.length > 0){
return this.getTitle(snapshot.children[0]);
}
else if(!!snapshot.data && !!snapshot.data['titleKey']){
return snapshot.data['titleKey'];
}
else{
return '';
}
}
似乎有点hacky但有效。
<强>旧强>
您可以尝试以下,
{
path: 'conversation/:otherId',
component: MessageConversationComponent,
data: {titleKey: 'XXX'},
// add below resolve
resolve: {
titleKey: MessageConversationResolve
}
}
添加新服务 MessageConversationResolve.ts ,并在提供商中正确添加。
import { Injectable } from '@angular/core';
import { Router, Resolve,ActivatedRouteSnapshot } from '@angular/router';
import { Observable } from 'rxjs/Observable';
@Injectable()
export class AdminDetailResolve implements Resolve<any> {
constructor(private router: Router,
private titleService: Title) {}
resolve(route: ActivatedRouteSnapshot): Observable<any> | Promise<any> | any {
// route.data will give you the titleKey property
// console.log(route.data);
// you may consume titleService here to setTitle
return route.data.titleKey;
}
}
以下是支持上述解决方案的角度版本,
Angular 2 version : 2.0.0-rc.5
Angular Router version : 3.0.0-rc.1
希望这会有所帮助!!