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,
  ];

Что, если данные пользователя будут изменены пользователями, без вызова API на бэкэнд, как вы узнаете, изменились ли они, разве динамические маршруты, такие как /user/:username, не являются лучшим решением для вас!

Naren Murali 15.07.2024 09:44

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

The Segfault 15.07.2024 11:56
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Angular и React для вашего проекта веб-разработки?
Angular и React для вашего проекта веб-разработки?
Когда дело доходит до веб-разработки, выбор правильного front-end фреймворка имеет решающее значение. Angular и React - два самых популярных...
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Мы провели Twitter Space, обсудив несколько проблем, связанных с последними дополнениями в Angular. Также прошла Angular Tiny Conf с 25 докладами.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
Мое недавнее углубление в Angular
Мое недавнее углубление в Angular
Недавно я провел некоторое время, изучая фреймворк Angular, и я хотел поделиться своим опытом со всеми вами. Как человек, который любит глубоко...
Освоение Observables и Subjects в Rxjs:
Освоение Observables и Subjects в Rxjs:
Давайте начнем с основ и постепенно перейдем к более продвинутым концепциям в RxJS в Angular
0
2
119
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 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",
...

О боже, я полностью уклоняюсь от этой части документации... Спасибо. Но теперь мне интересно, как передать все мои пользовательские данные маршруту. В документации можно определить маршрут, но я также хочу, чтобы маршрут содержал весь мой пользовательский объект. в качестве данных. Может быть, что-то вроде /products/1?name=charlie&[email protected] /products/555?name=marie&[email protected]

The Segfault 15.07.2024 12:10

@TheSegfault Да, вы можете выполнить вызов API ngOnInit, который извлекает данные, затем Angular SSR предварительно отобразит HTML с помощью этого вызова API и заполнит HTML, чтобы HTML мог видеть все данные во время сканирования веб-страниц.

Naren Murali 15.07.2024 12:11

Большое спасибо, SSR достаточно умен, чтобы использовать то, что он находит в ngOnInit каждого маршрута, и совершать вызов, это потрясающе!

The Segfault 15.07.2024 12:13

Другие вопросы по теме