Как избежать использования клиентов API во время рендеринга на стороне сервера и передать их клиенту в Angular Universal?

У меня есть довольно тривиальный компонент Angular, который служит компонентом маршрутизации маршрута домашней страницы модуля Angular. Я конвертирую этот проект в Angular Universal, чтобы воспользоваться преимуществами рендеринга на стороне сервера. Компонент делает что-то очень простое: перечисляет данные, полученные из разбитого на страницы API.

Пытаюсь добиться такого эффекта:

  • Визуализируйте компонент с его базовым шаблоном и бизнес-логикой
  • Сделайте первый вызов API внутри метода компонента ngOnInit () не на стороне сервера, а ТОЛЬКО на стороне клиента.

Моя первая попытка была:

  ngOnInit() {
    if (isPlatformBrowser(PLATFORM_ID)) {
      console.log('in the browser');
      // Load the first chunk of data only
      // within the browser (not on server side rendering)
      const page = 1;
      this.fetchNextPage(page);
    }
  }

Это не работает. У меня не вызывается ни console.log, ни fetchNextPage() метод. Если я удалю обертку if(), рендеринг на стороне сервера успешно вызовет метод fetchNextPage() и вызовет целевой API для получения первой страницы данных, но я бы хотел избежать влияния NodeJS -> calling the real backend API на производство. Я хотел бы сохранить стандартизированный Frontend -> calling the real backend API, который действителен и без SSR. Моя цель использования SSR - быстрее выполнить First Contentful Paint и SO. Это не для того, чтобы откладывать полное взаимодействие API до межсерверного взаимодействия.


person Dzhuneyt    schedule 02.04.2019    source источник


Ответы (1)


Вы должны иметь возможность использовать DI Angular, чтобы предоставить вам необходимую информацию следующим образом.

import { PLATFORM_ID, Inject } from '@angular/core';
import { isPlatformBrowser } from '@angular/common';

constructor(@Inject(PLATFORM_ID) private platformId: Object) {
  const isServer = !isPlatformBrowser(platformId);

  if (!isServer) {
      console.log('in the browser');
      // Load the first chunk of data only
      // within the browser (not on server side rendering)
      const page = 1;
      this.fetchNextPage(page);
  }
}
person peinearydevelopment    schedule 02.04.2019
comment
Спасибо! Виновником здесь является внедрение PLATFORM_ID с использованием DI, а не просто его импорт и использование! Это небольшая разница, но все же имеет значение. - person Dzhuneyt; 10.04.2019
comment
Спасибо тебе за это. Мне это нужно в моем приложении для рендеринга ngx-masonry на клиенте, поскольку он не работает при рендеринге на стороне сервера. Я использую <div *ngIf="!isServerRendering">, чтобы решить, отображать ли содержимое div или нет - person se22as; 21.08.2020