Angular如何根据路径更改navmenu标头

时间:2018-01-25 15:45:21

标签: angular angular2-routing

我正在使用Angular 4 +在当前项目中处理仪表板布局。

当用户在应用的不同部分之间导航时,我需要更新navmenu标题标题以反映应用的当前部分。

enter image description here

作为用户访问设置的示例,“页面标题”应更改为“设置”

enter image description here

该项目基于.net core 2 Angular模板 下面是构建应用程序路由以及仪表板路由的代码。

navigation.service

import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';

@Injectable()
export class NavigationService {
    private titleSource = new BehaviorSubject<string>("Page Title");
    currentTitle = this.titleSource.asObservable();

    constructor() {
    }

    changeTitle(title: string) {
        this.titleSource.next(title);
    }
}

应用-routing.module

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

import { HomeComponent } from "./components/home/home.component";

const appRoutes: Routes = [
    { path: '', redirectTo: 'home', pathMatch: 'full' },
    { path: 'home', component: HomeComponent },
    { path: '**', redirectTo: 'home' }
]

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

app.module.shared

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';

import { AppRoutingModule } from './app-routing.module';
import { DashboardModule } from "./components/dashboard/dashboard.module";

import { UtilsModule } from "./components/shared/shared.module";
//app components
import { AppComponent } from './components/app/app.component';

import { NavigationService } from "./services/navigation.service";

@NgModule({
    declarations: [
        AppComponent,

    ],
    imports: [
        SharedModule,
        DashboardModule,
        AppRoutingModule,
        DevExtremeModule,
        CommonModule,
        HttpModule,
        FormsModule
    ],
    providers: [NavigationService]
})
export class AppModuleShared {
}

仪表板routing.module

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

import { DashboardComponent } from "./dashboard.component";
import { SettingsProfileComponent } from "./settings/settingsProfile/settings.profile.component";
import { SettingsEmailComponent } from "./settings/settingsEmail/settings.email.component";
import { UsersListComponent } from "./users/users.list.component";

export const dashboardRoutes: Routes = [
    {
        path: 'dashboard',
        component: DashboardComponent,
        children: [{
            path: 'settings',
            data: { title: 'Settings' },

            children: [{
                path: 'profile',
                component: SettingsProfileComponent
            },
            {
                path: 'email',
                component: SettingsEmailComponent
            }]
        }, {
                path: 'users',
                data: { title: 'Users' },
                children: [{
                    path: '',
                    component: UsersListComponent
                }]
        }]
    }
];

@NgModule({
    imports: [
        RouterModule.forChild(dashboardRoutes)
    ],
    exports: [RouterModule]
})
export class DashboardRoutingModule { }

dashboard.module

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { UtilsModule } from "../shared/shared.module";

import { DashboardRoutingModule } from "./dashboard-routing.module";

import { DashboardComponent } from './dashboard.component';
import { SettingsProfileComponent } from "./settings/settingsProfile/settings.profile.component";
import { SettingsEmailComponent } from "./settings/settingsEmail/settings.email.component";
import { UsersListComponent } from "./users/users.list.component";

@NgModule({
    imports: [
        CommonModule,
        UtilsModule,
        DashboardRoutingModule
    ],
    declarations: [
        DashboardComponent,
        SettingsProfileComponent,
        SettingsEmailComponent,
        UsersListComponent,
    ],
    providers: []
})
export class DashboardModule {
}

我试图避免在每个组件中使用OnInit。是否可以仅在路由中执行此操作?该项目很早就开始了,如果有任何关于如何实现这一目标的其他建议,我们可以随时改变。

2 个答案:

答案 0 :(得分:3)

有很多方法可以解决这个问题。一种可能的解决方案是收听路由器事件,并根据它们决定应显示哪些内容。

此方法首先要求导入导航状态,例如,路线更改结束时。像这样:

import { Router, NavigationEnd } from '@angular/router';

然后你需要知道这个,例如像这样。

constructor ( private router:  Router ) {
router.events.subscribe( (event) => ( event instanceof NavigationEnd ) && this.handleRouteChange() )

}

一旦您能够检测到导航中的变化,您就可以看到,它是什么路线并基于此进一步做出决定。例如:

  handleRouteChange = () => {
    if (this.router.url.includes('some_key_part_of_url') {
     do what ever you want to do with your content...
    }
  };

您不一定要分析网址的实际内容,您可以决定其他路由器属性。请阅读the docs on router

答案 1 :(得分:2)

另一种选择可能是路线防护/路线解析器。您可以为每条路线添加一个保护/解析器,并让它读取您的数据属性。

以下是一个示例解析器:

import { Injectable } from '@angular/core';
import { Resolve, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';

import { Observable } from 'rxjs/Observable';

import { IMovie } from './movie';
import { MovieService } from './movie.service';

@Injectable()
export class MovieResolver implements Resolve<IMovie> {

    constructor(private movieService: MovieService,
                private navigationService: NavigationService) { }

    resolve(route: ActivatedRouteSnapshot,
            state: RouterStateSnapshot): boolean {
        const title = route.data['title'];
        this.navigationService.changeTitle(title);
        return true;
    }
}

如上所述。