Node.js 提供从节点到角度的值

Node.js 提供从节点到角度的值,node.js,angular,angular-universal,server-side-rendering,Node.js,Angular,Angular Universal,Server Side Rendering,我们有一个Angular通用应用程序,在运行服务器端时,需要将一个值从node.js传递给Angular。我们通过在server.ts中使用以下代码解决了此问题: const theValue: TheType = nodeLogicToRetrieveValue(); app.engine('html', (_, options, callback) => { let engine = ngExpressEngine({ bootstrap: AppServerModule

我们有一个Angular通用应用程序,在运行服务器端时,需要将一个值从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)
});
这可以正常工作,但起毛会发出以下警告:

get已弃用:从v4.0.0开始,使用Type或InjectionToken

我们尝试将其更改为,以便使用InjectionToken(
new InjectionToken('theKey')
)或类型而不是字符串,但这不起作用:

错误:StaticInjectorError(AppServerModule)[类型]: 静态注入错误(平台:核心)[类型]: NullInjectorError:没有类型的提供程序


是否只能通过字符串标记将值从节点传递到角度?

可以通过提供一个以字符串(用作键)作为值的InjectionToken来完成。InjectionToken可以键入到
类型
,lint不会发出警告

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

代币。ts

export const TOKEN = new InjectionToken<TheType>('theKey');
providers: [
    ....
    { provide: TOKEN, useValue: 'theKey', deps: [] }
]
constructor(@Optional() @Inject(TOKEN) private token: InjectionToken<TheType>, ...){
    if (isPlatformServer(this.platformId)) {
       this.theValue = this.injector.get(this.token);
    }
}
注入令牌并用
@Optional()
修饰它,因为浏览器也会尝试注入令牌(由于缺少提供程序而失败)。从节点传递的值仅与服务器相关,不需要为
appModule
提供InjectionToken

应用程序组件.ts

export const TOKEN = new InjectionToken<TheType>('theKey');
providers: [
    ....
    { provide: TOKEN, useValue: 'theKey', deps: [] }
]
constructor(@Optional() @Inject(TOKEN) private token: InjectionToken<TheType>, ...){
    if (isPlatformServer(this.platformId)) {
       this.theValue = this.injector.get(this.token);
    }
}
构造函数(@Optional()@Inject(TOKEN)私有令牌:InjectionToken,…){
if(isPlatformServer(this.platformId)){
this.theValue=this.injector.get(this.token);
}
}

可以通过提供一个字符串(用作键)作为值的InjectionToken来完成。InjectionToken可以键入到
类型
,lint不会发出警告

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

代币。ts

export const TOKEN = new InjectionToken<TheType>('theKey');
providers: [
    ....
    { provide: TOKEN, useValue: 'theKey', deps: [] }
]
constructor(@Optional() @Inject(TOKEN) private token: InjectionToken<TheType>, ...){
    if (isPlatformServer(this.platformId)) {
       this.theValue = this.injector.get(this.token);
    }
}
注入令牌并用
@Optional()
修饰它,因为浏览器也会尝试注入令牌(由于缺少提供程序而失败)。从节点传递的值仅与服务器相关,不需要为
appModule
提供InjectionToken

应用程序组件.ts

export const TOKEN = new InjectionToken<TheType>('theKey');
providers: [
    ....
    { provide: TOKEN, useValue: 'theKey', deps: [] }
]
constructor(@Optional() @Inject(TOKEN) private token: InjectionToken<TheType>, ...){
    if (isPlatformServer(this.platformId)) {
       this.theValue = this.injector.get(this.token);
    }
}
构造函数(@Optional()@Inject(TOKEN)私有令牌:InjectionToken,…){
if(isPlatformServer(this.platformId)){
this.theValue=this.injector.get(this.token);
}
}

我必须调整Emil的答案才能让它起作用(我使用的是angular 10)

定义令牌:
export const CLIENT_ID=new InjectionToken('CLIENT-ID');
提供来自服务器的值:
app.engine('html',ngExpressEngine({
引导:AppServerModule,
供应商:[
{
提供:客户ID,
useValue:'MyClientId',
},
],
})(如有的话);
将值注入客户端:
构造函数(@Optional()@Inject(CLIENT_ID)private clientId:string){
console.log(this.clientId);
}

我必须调整Emil的答案才能让它起作用(我使用的是angular 10)

定义令牌:
export const CLIENT_ID=new InjectionToken('CLIENT-ID');
提供来自服务器的值:
app.engine('html',ngExpressEngine({
引导:AppServerModule,
供应商:[
{
提供:客户ID,
useValue:'MyClientId',
},
],
})(如有的话);
将值注入客户端:
构造函数(@Optional()@Inject(CLIENT_ID)private clientId:string){
console.log(this.clientId);
}