簡體   English   中英

如何在 web shell 模塊內提供應用功能路由

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM