如何在节点脚本中重用Angular 6 API服务?

时间:2018-10-15 17:06:47

标签: node.js angular typescript

我想在节点脚本中重用某些Angular 6 API服务,并且遇到了一些麻烦,无法正确初始化所有内容。

API服务是使用Swagger Codegen(-l typescript-angular)生成的,例如:

@Injectable()
export class UserService {

    constructor(protected httpClient: HttpClient, @Optional()@Inject(BASE_PATH) basePath: string, @Optional() configuration: Configuration) { 
      ... 
    }

}

这些服务在我的Angular 6应用程序中可以完美地工作,我现在想在节点中使用它们来编写一些脚本。我知道Swagger Codegen也能够生成一个纯TypeScript客户端,但是仍然希望重用现有的Angular服务,以使代码库更加一致。

我当时面临的挑战是如何在没有依赖注入的情况下调用此构造函数。

在没有依赖注入的情况下获得有效的HttpClient对象似乎非常困难。在AngularJS中,我曾经依靠Axios来实现此功能,但是该库似乎不再提供与HttpClient相同的接口(仍然可以保证提供,而不是Angular 6中较新的可观察对象)。

在我看来,会有两种选择:

  1. 以某种方式获取HttpClient对象->无法使其正常工作。
  2. 注入另一个暴露相同接口的HTTP客户端对象->似乎找不到一个。

有人知道如何正确解决这个问题吗?

干杯

M。

1 个答案:

答案 0 :(得分:6)

HttpClient不应手动实例化,并且这不是简单的过程,因为它具有很多依赖性。 Angular注入器完成了依赖注入的所有工作,应该用于获取实例。

this answer所示,可以通过设置模块并对其进行引导来获得Angular提供程序(HttpClient)的实例。

UserService应该使用非常相似的方法。这是简化但可行的示例:

import 'zone.js/dist/zone-node';
import 'reflect-metadata';

import {Injector, Injectable, NgModule } from '@angular/core'
import {HttpClient, HttpClientModule} from '@angular/common/http'
import {ServerModule, platformDynamicServer} from '@angular/platform-server';

@Injectable()
export class UserService {
  constructor(protected httpClient: HttpClient) { 
    httpClient.get('https://google.com/').subscribe(console.log, console.error);
  }
}

@NgModule({
  imports: [ServerModule, HttpClientModule],
  providers: [UserService]
})
export class AppModule {
  ngDoBootstrap() {}
}

(async () => {
    const platform = platformDynamicServer();
    const appModule = await platform.bootstrapModule(AppModule);
    const userService = appModule.injector.get(UserService);
})()
.catch(console.error);

它需要兼容的TypeScript配置,例如:

{
  "compilerOptions": {
    "target": "es6",
    "module": "commonjs",
    "strict": true,
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true
  }
}