Конфигурация Angular Universal и ngx-datable

Я пытаюсь преобразовать какое-то старое приложение в универсальный Angular (с Angular 9), и у меня проблема с настройкой ngx-datable для работы с рендерингом на стороне сервера. Я следовал официальному руководству по его настройке https://github.com/swimlane/ngx-datatable/blob/master/docs/universal/server-side-rendering.md

Но у меня проблема с размещением провайдеров

providers: [
  {
    provide: ScrollbarHelper,
    useClass: ServerScrollBarHelper
  },
  {
    provide: DimensionsHelper,
    useClass: ServerDimensionsHelper
  }
];

Мой AppRoutingModule лениво загружает другие подмодули с помощью loadChildren. Я также использую SharedModule, где определены большинство моих клиентских провайдеров.

Я обнаружил, что могу получить доступ к ServerScrollBarHelper и ServerDimensionsHelperthem, только если я определю их внутри подмодулей, но проблема в том, что они должны работать только тогда, когда происходит рендеринг на стороне сервера Angular. Я попытался поместить их в список AppServerModule провайдеров, но потом они как будто не определены.

Есть ли какой-нибудь пример этого, или кто-нибудь знает, как я могу легко загружать разных поставщиков для серверного и клиентского рендеринга, не слишком сильно меняя структуру моего приложения?

РЕДАКТИРОВАТЬ: поэтому я сузил свою проблему до ленивой загрузки, потому что с модулями загрузки layz вы не можете переопределить своих провайдеров из AppRoutingModule, потому что каждый модуль использует свой собственный инжектор. Я все еще не могу найти решение, не удалив из проекта ленивую загрузку, что звучит неправильно.


person DejanG    schedule 29.04.2020    source источник
comment
Я думаю, вы могли бы использовать фабрику для загрузки правильной реализации на основе платформы   -  person David    schedule 30.04.2020


Ответы (1)


Мое текущее решение этой проблемы.

В каждый модуль с отложенной загрузкой я вставлял ServerScrollBarHelper & ServerDimensionsHelper, чтобы иметь к ним доступ даже при отложенной загрузке. Но я изменил их код, поэтому они по-разному ведут себя на сервере и в браузере.

   import { Injectable, Inject, Injector, PLATFORM_ID } from '@angular/core';
import { Request } from 'express';
import { REQUEST } from '@nguniversal/express-engine/tokens';
import { DimensionsHelper } from '@swimlane/ngx-datatable';
import { isPlatformBrowser, isPlatformServer } from '@angular/common';

@Injectable()
export class ServerDimensionsHelper extends DimensionsHelper {

    clientRqst;
    constructor(@Inject(PLATFORM_ID) private platformId: Object, injectctor: Injector) {
        super();
        if (isPlatformServer(this.platformId)) {
            this.clientRqst = injectctor.get(REQUEST);
        }
    }

    getDimensions(element: Element): ClientRect {
        if (isPlatformBrowser(this.platformId)) {
            return super.getDimensions(element);
        } else {
            console.log(this.clientRqst.headers);
            const width = parseInt(this.clientRqst.headers.cookie['CH-DW'], 10) || 1000;
            const height = parseInt(this.clientRqst.headers.cookie['CH-DH'], 10) || 800;

            const adjustedWidth = width;
            const adjustedHeight = height;

            return {
                height: adjustedHeight,
                bottom: 0,
                top: 0,
                width: adjustedWidth,
                left: 0,
                right: 0
            };
        }
    }
}




import { ScrollbarHelper } from '@swimlane/ngx-datatable';
import { Injectable, Inject, PLATFORM_ID } from '@angular/core';
import { DOCUMENT, isPlatformBrowser } from '@angular/common';

@Injectable()
export class ServerScrollBarHelper extends ScrollbarHelper {
    width: number;

    constructor(@Inject(DOCUMENT) document, @Inject(PLATFORM_ID) private platformId: Object) {
        super(document);
        this.width = 16; // use default value
    }

    getWidth(): number {
        if (isPlatformBrowser(this.platformId)) {
            return super.getWidth();
        } else {
            return this.width;
        }

    }
}
person DejanG    schedule 30.04.2020