编程语言
首页 > 编程语言> > javascript-StaticInjectorError [HttpClent]:不支持函数/类

javascript-StaticInjectorError [HttpClent]:不支持函数/类

作者:互联网

我试图手动注入HttpClientModule,该HttpClientModule在独立于应用程序之外(可能是!)运行.在使用静态喷油器之前,我使用了反射式喷油器,并且代码运行良好,但是现在不建议使用反射式喷油器,我想使用静态喷油器更新代码.

//appInjector.ts
export class AppInjector {

  private static _instance: AppInjector = new AppInjector();
  private _injector;

  constructor() {
    console.log('app-injector');
    AppInjector._instance = this;
    this._injector = ReflectiveInjector.resolveAndCreate([
        ...[getAnnotations(HttpClientModule)[0].providers],
        MY_HTTP_DEPENDENT_PROVIDERS
        ]);
        
  static getInstance(): AppInjector {
    return AppInjector._instance;
  }

  get(cls: any): any {
    return this._injector.get(cls);
  }
}
//someFile.ts
const translate = AppInjector.getInstance().get(TranslateResource);

参考This Post
用于注释fn.
现在,当我尝试通过静态注入使用Http客户端时,它给出了错误:
StaticInjectorError [HttpClent]:不支持函数/类

//app module
@NgModule({
  imports: [],
  declarations: [],
  providers: [],
  entryComponents: [App]
})
export class AppModule {
  ngDoBootstrap(app) {
    console.log('bootstrapping');
    app.bootstrap(App);
  }

因此,如果我登录,它将登录应用程序注入器,然后进行引导.

解决方法:

应该使用StaticInjector替代不需要Reflect API的ReflectiveInjector. getAnnotations是低级黑客,它可能无法在当前状态下与StaticInjector一起使用.另外,getAnnotations在设计上与AOT不兼容.

最好按照应该由框架完成的方式为模块创建注入器,即模块应该被引导.由于没有要引导的组件,因此应指定ngDoBootstrap挂钩.

默认情况下,引导过程是异步的.如果这不是问题,则可以链接初始化诺言以获取模块实例.

example

@NgModule({
  imports: [BrowserModule, HttpClientModule]
})
export class MyHttpModule {
  static httpClient?: HttpClient;
  httpClient?: HttpClient;

  constructor(private _injector: Injector) {}

  ngDoBootstrap() {
    MyHttpModule.httpClient = this.httpClient = this._injector.get(HttpClient);
  }  
}

platformBrowserDynamic().bootstrapModule(MyHttpModule)
.then((myHttpModule: NgModuleRef<MyHttpModule>) => {
    // HttpClient instance is available here
    const httpClient = myHttpModule.instance.httpClient;
    httpClient.get('/foo', { responseType: 'text'}).subscribe();
})
.catch(err => console.error(err));

这种方法与JIT和AOT都兼容(开箱即用,它与Angular分开使用时非常适合使用HttpClient,因为这可以大大减少占用空间).

否则,可以改为执行自定义同步引导程序.这是可能的,因为HttpClient不需要异步初始化.

一个example

@NgModule({
  imports: [BrowserModule, HttpClientModule]
})
export class MyHttpModule {
  static httpClient?: HttpClient;

  constructor(public _injector: Injector) {
    MyHttpModule.httpClient = this._injector.get(HttpClient);
  }

  ngDoBootstrap() {}  
}

const platform = platformBrowserDynamic();
const compiler = platform.injector.get(CompilerFactory).createCompiler();
const moduleFactory = compiler.compileModuleSync(MyHttpModule);

platform.bootstrapModuleFactory(moduleFactory)
.catch(err => console.error(err));

const httpClient = MyHttpModule.httpClient;
httpClient.get('/foo').subscribe();

这将在JIT中起作用,但是Angular CLI在上面的代码中无法有效地处理AOT.该代码涉及编译器,而在AOT编译模式下则不需要(这就是其目的).为了使用AOT,应使用ngc编译器对其进行编译,并应创建一个使用模块工厂的单独入口点. Bootstrap例程变得更加简单,因为它不涉及编译器,例如:

...
import { platformBrowser } from '@angular/platform-browser-dynamic';
import { AppModuleNgFactory } from '<path to aot>/src/app/my-http-module.ngfactory';

const platform = platformBrowser();
platform.bootstrapModuleFactory(AppModuleNgFactory)
.catch(err => console.error(err));

const httpClient = MyHttpModule.httpClient;
httpClient.get('/foo').subscribe();

标签:angular-httpclient,javascript,angular,typescript
来源: https://codeday.me/bug/20191011/1895131.html