从Node向Angular Universal提供价值

3
我们有一个Angular Universal应用程序,需要在服务器端运行时从node.js传递一个值到angular。我们通过在server.ts中使用以下代码来解决这个问题:
const theValue: TheType = nodeLogicToRetrieveValue();

app.engine('html', (_, options, callback) => {
  let engine = ngExpressEngine({
    bootstrap: AppServerModuleNgFactory,
    providers: [
      provideModuleMap(LAZY_MODULE_MAP),
      { provide: 'theKey', useFactory: () => theValue, deps: [] }
    ]
  });
  engine(_, <any>options, callback)
});

在组件中,我们使用以下代码解析此对象:
if (isPlatformServer(this.platformId)) {
  this.theValue = this.injector.get('theKey');
}

这个代码可以正常工作,但是代码检查会给出以下警告:

get已经过时:从v4.0.0开始使用Type<T>或InjectionToken<T>

我们尝试将其更改为使用InjectionToken (new InjectionToken<TheType>('theKey'))或类型而不是字符串,但这样无法正常工作:

错误:StaticInjectorError(AppServerModule)[TheType]: StaticInjectorError(Platform: core)[TheType]: NullInjectorError:TheType没有提供者!

是否只能通过字符串令牌从node传递值到angular中?

2个回答

3

我需要修改Emil的答案才能让它在我的Angular 10上运行。

定义token:

export const CLIENT_ID = new InjectionToken<string>('client-id');

从服务器提供值:

app.engine('html', ngExpressEngine({
    bootstrap: AppServerModule,
    providers: [
      {
        provide: CLIENT_ID,
        useValue: 'MyClientId',
      },
    ],
  }) as any);

在客户端中注入值:
constructor(@Optional() @Inject(CLIENT_ID) private clientId: string){
  console.log(this.clientId);
}

3

您可以通过提供一个InjectionToken,其字符串值(用作键)为value来完成。InjectionToken可以类型化为TheType,lint将不会发出警告。

在单独的文件中创建InjectionToken以避免循环依赖。

tokens.ts

export const TOKEN = new InjectionToken<TheType>('theKey');

在 appServerModule 中提供 InjectionToken。

app.server.module.ts

providers: [
    ....
    { provide: TOKEN, useValue: 'theKey', deps: [] }
]

注入令牌并用@Optional()修饰,因为浏览器也会尝试注入令牌(由于缺乏提供者而失败)。从节点传递的值仅与服务器相关,并且无需为appModule提供InjectionToken。

app.component.ts

constructor(@Optional() @Inject(TOKEN) private token: InjectionToken<TheType>, ...){
    if (isPlatformServer(this.platformId)) {
       this.theValue = this.injector.get(this.token);
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接