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挂钩.
默认情况下,引导过程是异步的.如果这不是问题,则可以链接初始化诺言以获取模块实例.
@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