StaticInjectorError [HttpClent]:不支持函数/类 [英] StaticInjectorError[HttpClent]: Function/class not supported

查看:88
本文介绍了StaticInjectorError [HttpClent]:不支持函数/类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am trying to inject the HttpClientModule manually which runs outside independent(may be!) from app. Before static injector i was using reflective injector and code was working fine but now that reflective injector has been deprecated and I want to update my code with static injector.

//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);

请参考这篇文章 用于注释fn. 现在,当我尝试通过静态注入使用Http客户端时,它给出了错误: StaticInjectorError[HttpClent]: Function/class not supported

refer This Post for annotation fn. Now when i am trying to use Http client with static inject it gives error: StaticInjectorError[HttpClent]: Function/class not supported

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

因此,如果我登录,它将先记录app-injector,然后记录bootstrapping.

so if i log it will log app-injector and then bootstrapping.

推荐答案

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

StaticInjector is supposed to be a replacement for ReflectiveInjector that doesn't require Reflect API. getAnnotations is low-level hack and it likely won't work with StaticInjector in its current state. Also, getAnnotations is incompatible with AOT by design.

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

It's preferable to create an injector for a module the way it is supposed to be done by the framework, i.e. a module should be bootstrapped. Since there is no component to bootstrap, ngDoBootstrap hook should be specified.

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

By default, bootstrap process is asynchronous. If this is not a problem, initialization promise can be chained to get module instance.

示例:

@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,因为这样可以大大减少占用空间).

This approach is compatible with both JIT and AOT (which is good for using HttpClient apart from Angular because this lowers the footprint significantly) out of the box.

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

Otherwise custom synchronous bootstrap routine can be performed instead. This is possible because HttpClient doesn't require asynchronous initialization.

示例:

@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例程变得更加简单,因为它不涉及编译器,例如:

This will work in JIT, but AOT can't be efficiently handled by Angular CLI in the code above. The code involves the compiler, which isn't needed in AOT compilation mode (that's its purpose). In order to use AOT, it should be compiled with ngc compiler and a separate entry point that uses module factories should be created. Bootstrap routine becomes even simpler, because it doesn't involve compiler, something like:

...
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();

这篇关于StaticInjectorError [HttpClent]:不支持函数/类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆