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

2023-12-11

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

refer 这个帖子用于注释 fn。 现在,当我尝试使用带有静态注入的 Http 客户端时,会出现错误: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.


StaticInjector应该是替代品ReflectiveInjector这不需要Reflect API. getAnnotations是低级黑客,它可能无法使用StaticInjector在目前的状态下。还,getAnnotations在设计上与 AOT 不兼容。

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

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

An 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 兼容(这有利于使用HttpClient除了 Angular 之外,因为这可以显着降低占用空间)开箱即用。

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

An 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应该创建编译器和使用模块工厂的单独入口点。引导例程变得更加简单,因为它不涉及编译器,例如:

...
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();
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

StaticInjectorError[HttpClent]:不支持函数/类 的相关文章

随机推荐