Angular 18 SSR Standalone — маршруты, которые будут генерироваться на основе данных перед начальной загрузкой

Я не могу понять, как заставить это работать без использования теневых магических волшебников, так что, возможно, я что-то упускаю.

Мой пример случая:

У меня есть простое приложение Angular 18 SSR с маршрутом домой и пользователем/:имя пользователя.

Я не хочу запрашивать свою базу данных со своего веб-сайта, поэтому мне нужно заранее получить информацию обо всех своих пользователях и соответствующим образом сгенерировать маршруты.

Если я получу эти данные пользователей:

  { name: 'alice', email: '[email protected]' },
  { name: 'bob', email: '[email protected]' },
  { name: 'charlie', email: '[email protected]' },

Я хочу, чтобы Angular SSR создавал мой сайт с маршрутами:

  • пользователь/алиса
  • пользователь/Боб
  • пользователь/Чарли

Я пробовал добавлять их динамически вот так

 addUserRoutes(users: any[]) {
    const newRoutes = users.map(user => ({
      path: 'user/' + user.name,
      component: UserComponent,
      resolve: { user: user },
     }));
   this.router.resetConfig([...this.router.config, ...newRoutes]);
 }

Если я распечатаю файл router.config, я получу все нужные маршруты, но SSR не сгенерировал их, поэтому я не могу найти их на своем веб-сайте, поэтому это решение не работает.

Я пытался получить данные до начальной загрузки

export function initializeApp(http: HttpClient) {
  return (): Promise<any> =>
    firstValueFrom(
      http
        .get('generated/db-data.json')
        .pipe(
          map((data: any) => data.users),
    ));
}

export const appConfig: ApplicationConfig = {
  providers: [
    provideZoneChangeDetection({ eventCoalescing: true }),
    provideRouter(routes),
    provideClientHydration(),
    provideAngularSvgIcon(),
    provideHttpClient(),
    {
      provide: APP_INITIALIZER,
      useFactory: initializeApp,
      multi: true,
      deps: [HttpClient],
    },
  ]
};

Но тогда я не знаю, как использовать этих пользователей для обновления моего массива маршрутов в моем ProvideRouter(routes).

Я собираюсь просто использовать данные из InitializeApp напрямую для динамического создания массива маршрутов и попытаться использовать его напрямую, обновляя в ProvideRouter(routes).

Обновлено: я обсуждаю это со своими коллегами, и на самом деле моя база данных на самом деле представляет собой большой json, и я перестану выполнять асинхронные вызовы и буду заниматься внедрением зависимостей и т. д., и просто

import userData from '../../public/generated/db-data.json';


 function generateRoutes(): Routes {
  const userRoutes = userData.users.map(user => ({
    path: 'user/' + user.name,
    component: UserComponent,
    data: { user },
  }));

  return [
    ...userRoutes,
  ];

🤔 А знаете ли вы, что...
Angular обладает многими инструментами и рекомендациями по безопасности приложений.


119
1

Ответ:

Решено

Лучшее решение — использовать параметризованные маршруты предварительной визуализации, где вы указываете, какие маршруты вы хотите предварительно визуализировать, а затем SSR визуализирует эти маршруты как статические маршруты, и не будет ненужных вызовов API для получения пользователей во внешнем интерфейсе.

Сначала вам нужно настроить параметризованный маршрут, например user/:username или что-то в этом роде.

Затем вы можете написать сценарий, который генерирует routes.txt из вызова API, который получает список пользователей из БД, затем при сборке приложения файл Routes.txt обрабатывается, и вы получаете желаемый результат.

Этот скрипт будет обработан приложением Angular перед запуском npm run start или npm run build.

...
"start": "node dynamic-routes.js && ng serve",
"build": "node dynamic-routes.js && ng build",
...