微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐