解决这个问题的方法是使用Angular的TransferState模块来避免页面渲染两次。TransferState模块允许在服务器和客户端之间传输状态,以便在服务器渲染期间收集数据并在客户端渲染期间重新使用。
以下是一个示例代码,展示了如何使用TransferState模块来解决这个问题:
import { enableProdMode } from '@angular/core';
import { provideModuleMap } from '@nguniversal/module-map-ngfactory-loader';
import { ServerModule, ServerTransferStateModule } from '@angular/platform-server';
import { AppModule } from './app/app.module';
import { AppComponent } from './app/app.component';
// Enable production mode
enableProdMode();
// Create an instance of the app module
const app = new AppModule(AppComponent);
// Export a function that returns the server-side rendered HTML
export default function (params: any, url: string): Promise {
return platformDynamicServer().bootstrapModule(app).then(moduleRef => {
const state = moduleRef.injector.get(TransferState);
state.set('REQUEST', url);
const appRef = moduleRef.injector.get(ApplicationRef);
const stateTransferService = moduleRef.injector.get(StateTransferService);
const transferData = stateTransferService.get();
if (transferData) {
stateTransferService.inject();
stateTransferService.set(transferData);
}
return appRef.isStable.pipe(
filter(stable => stable),
take(1),
switchMap(() => moduleRef.injector.get(PlatformState).renderToString())
).toPromise();
});
}
import { NgModule } from '@angular/core';
import { BrowserTransferStateModule, TransferState } from '@angular/platform-browser';
import { AppComponent } from './app.component';
@NgModule({
imports: [
BrowserModule.withServerTransition({ appId: 'my-app' }),
BrowserTransferStateModule,
// ...
],
declarations: [AppComponent],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule {
constructor(private transferState: TransferState) {
const data = this.transferState.get(key, null);
if (data) {
// Use the transferred data
} else {
// Make HTTP requests to get data
}
}
}
通过使用TransferState模块,可以避免Angular与universal一起渲染页面导致页面渲染两次的问题。它允许在服务器端收集数据并在客户端端重新使用,从而提高性能和用户体验。