我正在尝试将一些旧的应用程序转换为Angular Universal,并且在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
提供程序列表中,但就好像未定义它们一样。
是否有这样的示例,或者有人知道我可以轻松地为服务器渲染和客户端渲染轻松加载不同的提供程序,而又无需过多更改我的应用程序结构?
编辑:所以我将问题缩小为延迟加载,因为使用延迟加载模块,您无法从AppRoutingModule
覆盖提供程序,因为每个模块都使用自己的Injector。如果不从听起来不正确的项目中删除延迟加载,我仍然找不到解决方案。
我当前对这个问题的解决方案。
[在每个延迟加载的模块中,我注入了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 } from '@angular/common';
@Injectable()
export class ServerDimensionsHelper extends DimensionsHelper {
constructor(@Inject(REQUEST) private request: Request, @Inject(PLATFORM_ID) private platformId: Object) {
super();
}
getDimensions(element: Element): ClientRect {
if (isPlatformBrowser(this.platformId)) {
return super.getDimensions(element);
} else {
const width = parseInt(this.request.cookies['CH-DW'], 10) || 1000;
const height = parseInt(this.request.cookies['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;
}
}
}