[英]How to provide app feature routes within web shell module
我收到以下错误
Uncaught Error: NG0203: inject() must be called from an injection context such as a constructor, a factory function, a field initializer, or a function used with `EnvironmentInjector#runInContext`.
我正在尝试创建一个 Nx 库模块来共享 web shell 身份验证逻辑以与多个应用程序共享。 我希望每个应用程序都能够执行以下操作:
providers: [
{
provide: HOME_PAGE,
useValue: 'my-app-homepage',
},
{
provide: LOAD_FEATURE_ROUTES,
useValue: async () => (await import('./feature-routes')).FEATURE_ROUTES
},
],
但是我如何将它们放入我的库模块的路由中,以便像这样在中间使用
function createRoutes(): Routes {
const homePage = inject(HOME_PAGE)
const childRoutes = inject(LOAD_FEATURE_ROUTES)
return [
{
path: 'auth',
loadChildren: async () => (await import('./auth-routes')).AUTH_ROUTES,
},
{
path: homePage, // <---- I want to inject app feature routes
loadChildren: childRoutes
},
{ path: '', redirectTo: 'auth', pathMatch: 'full' },
{ path: '**', redirectTo: 'auth' },
];
}
显然以下错误的原因是但现在确定用什么替换它:
RouterModule.forRoot(inject(APP_ROUTES), {
scrollPositionRestoration: 'top',
})],
完整代码:
import { inject, InjectionToken, NgModule } from '@angular/core';
import { Routes, RouterModule, LoadChildrenCallback } from '@angular/router';
import { HOME_PAGE } from '@my-org/shared/auth-login/data-access/store';
export const APP_ROUTES = new InjectionToken<Routes>('APP_ROUTES');
export const LOAD_FEATURE_ROUTES = new InjectionToken<LoadChildrenCallback>('LOAD_FEATURE_ROUTES');
function createRoutes(): Routes {
const homePage = inject(HOME_PAGE)
const childRoutes = inject(LOAD_FEATURE_ROUTES)
return [
{
path: 'auth',
loadChildren: async () => (await import('./auth-routes')).AUTH_ROUTES,
},
{
path: homePage,
loadChildren: childRoutes
},
{ path: '', redirectTo: 'auth', pathMatch: 'full' },
{ path: '**', redirectTo: 'auth' },
];
}
@NgModule({
imports: [
RouterModule.forRoot(inject(APP_ROUTES), {
scrollPositionRestoration: 'top',
})],
providers: [
{
provide: APP_ROUTES,
useFactory: createRoutes,
deps: [
APP_ROUTES,
LOAD_FEATURE_ROUTES
]
}
],
exports: [RouterModule],
})
export class SharedAuthLoginRoutingModule {
}
注意我正在使用 Angular 15 并使用独立组件延迟加载 APP_ROUTES。
设法通过ROUTES
依赖注入来做到这一点
{
provide: ROUTES,
multi: true,
useFactory: createRoutes
}
const createRoutes = () => {
const homePage = inject(HOME_PAGE);
const featureChildrenRoutes = inject(LOAD_FEATURE_ROUTES);
console.log(homePage) // works
const routes: Routes = [
{
path: 'auth',
loadChildren: async () => (await import('@my-org/shared/auth-login/feature')).SharedAuthLoginFeatureModule;
},
},
/**
* App specific routes injected via `HOME_PAGE` and `LOAD_FEATURE_ROUTES`
*/
{
path: homePage,
loadChildren: featureChildrenRoutes,
canActivate: [AuthGuard],
data: { authGuardPipe: authPipeGenerator }
},
{ path: '', redirectTo: 'auth', pathMatch: 'full' },
{ path: '**', redirectTo: 'auth' },
];
return routes;
}
// tree shakeable injection token
export const HOME_PAGE = new InjectionToken<string>('HOME_PAGE', {
providedIn: 'root',
factory: () => { throw new Error(`Provider required e.g. { provide: HOME_PAGE, useValue: 'home' }`) }
});
// tree shakeable injection token
export const LOAD_FEATURE_ROUTES = new InjectionToken<LoadChildrenCallback | undefined>('LOAD_FEATURE_ROUTES', {
providedIn: 'root',
factory: () => {throw new Error(`Provide lazy loaded App specific routes e.g. \`async () => (await import('./app.routes')).appShellRoutes}\``)}
})
现在我可以让 AppModule import AppShellModule 导入 WebShellModule
AppModule - 只导入应用程序 shell
AppShellModule - 导入 web shell,定义应用程序功能路由
WebShellModule - 登陆页面 shell,带导航栏、身份验证(登录、注册页面等)
我的 WebShellModule 可跨多个应用重用
@NgModule({
imports: [
BrowserAnimationsModule,
HttpClientModule,
RootNgrxModule, // provide store, effects, router store
RouterModule.forRoot([], {
scrollPositionRestoration: 'top',
}),
FirebaseV7Module, // provide app, auth, firestore
HomePageComponent, // Standalone component, navbar
],
providers: [
{
provide: ROUTES,
multi: true,
useFactory: createRoutes
},
]
})
export class WebShellModule { }
AppShellModule 负责提供 DI 令牌,例如
{
provide: HOME_PAGE,
useValue: 'procurement',
},
{
provide: LOAD_FEATURE_ROUTES,
useValue: async () => {
return (await import('./procurement.routes')).procurementShellRoutes;
},
},
我还没有弄清楚所有事情,但这似乎是要采取的方向。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.