Angular 4路由中如何注入服务动态生成路径名称?
嘿,这个问题我之前也碰到过!在Angular里直接在静态路由配置里注入服务是行不通的,因为路由配置是在应用初始化的早期阶段就被解析了,这时候依赖注入容器还没完全准备好呢。不过别担心,有几种靠谱的方法能实现你想要的动态路由路径功能,我给你详细说说:
解决方案1:用
APP_INITIALIZER提前加载配置(最适合你的场景) 这个方法的核心是在应用启动前,先通过服务获取到路由路径的配置,把它存在一个可全局访问的地方,然后再让路由配置读取这个值。
步骤1:创建一个初始化服务来加载配置
首先我们需要一个服务,负责从你的xyzService里获取路由路径,并把它存为静态属性(这样路由配置就能直接访问到):
import { Injectable } from '@angular/core'; import { XyzService } from './path-to-your-xyz-service'; @Injectable({ providedIn: 'root' }) export class RouteConfigInitializer { // 默认值,防止加载失败时路由出错 static routePaths = { login: 'login' }; constructor(private xyzService: XyzService) {} // 加载配置的方法,如果你的getKey是异步的,就返回Promise loadConfig(): Promise<void> { return new Promise((resolve) => { // 同步获取路径的话直接赋值 const loginPath = this.xyzService.getKey('login'); RouteConfigInitializer.routePaths.login = loginPath; resolve(); // 如果是异步获取(比如HTTP请求),改成这样: // this.xyzService.getAsyncKey('login').then(loginPath => { // RouteConfigInitializer.routePaths.login = loginPath; // resolve(); // }); }); } }
步骤2:配置APP_INITIALIZER确保启动前加载完成
在你的根模块(AppModule)里,配置APP_INITIALIZER,让应用等待配置加载完成后再启动:
import { NgModule, APP_INITIALIZER } from '@angular/core'; import { RouteConfigInitializer } from './path-to-route-config-initializer'; @NgModule({ // ...其他模块、组件、导入配置 providers: [ { provide: APP_INITIALIZER, useFactory: (initializer: RouteConfigInitializer) => () => initializer.loadConfig(), deps: [RouteConfigInitializer], multi: true // 允许多个初始化器 } ] }) export class AppModule {}
步骤3:在路由配置里使用动态路径
现在你就可以在路由配置里直接引用我们提前加载好的静态属性了:
import { Routes, ModuleWithProviders, RouterModule } from '@angular/router'; import { LoginComponent } from './login.component'; import { PageNotFoundComponent } from './page-not-found.component'; import { RouteConfigInitializer } from './path-to-route-config-initializer'; export const routes: Routes = [ { path: '', redirectTo: `/${RouteConfigInitializer.routePaths.login}`, pathMatch: 'full' }, { path: RouteConfigInitializer.routePaths.login, component: LoginComponent, canActivate: [dbs.ConfigGuard] }, { path: '**', component: PageNotFoundComponent } ]; export const routing: ModuleWithProviders = RouterModule.forRoot(routes);
解决方案2:动态添加路由(适合子路由/延迟加载场景)
如果你的路由是属于某个延迟加载模块的,也可以在模块的构造函数里注入Router和xyzService,然后动态添加路由规则:
import { NgModule } from '@angular/core'; import { RouterModule, Router } from '@angular/router'; import { LoginComponent } from './login.component'; import { XyzService } from './path-to-your-xyz-service'; @NgModule({ imports: [RouterModule.forChild([])], exports: [RouterModule] }) export class AuthModule { constructor(private router: Router, private xyzService: XyzService) { const loginPath = this.xyzService.getKey('login'); // 把动态路由添加到路由配置的最前面 this.router.config.unshift({ path: loginPath, component: LoginComponent, canActivate: [dbs.ConfigGuard] }); } }
这种方法的好处是不需要提前加载配置,但不太适合主路由(因为主路由的配置在AppModule初始化时就已经被解析了)。
内容的提问来源于stack exchange,提问作者Ashish Ratan
相关产品推荐
相关产品推荐

