问题描述
我正在尝试手动注入 HttpClientModule
运行 独立于应用程序(可能是!).在使用静态注入器之前,我使用反射注入器并且代码工作正常,但现在反射注入器已被弃用,我想用静态注入器更新我的代码.
I am trying to inject the HttpClientModule
manually which runs 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]:不支持函数/类
refer This Postfor 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
应该替代 ReflectiveInjector
不需要 Reflect代码> API.
getAnnotations
是低级别的 hack,它可能无法在当前状态下与 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:
/src/app/my-http-module.ngfactory';const 平台 = platformBrowser();platform.bootstrapModuleFactory(AppModuleNgFactory).catch(err => console.error(err));const httpClient = MyHttpModule.httpClient;httpClient.get('/foo').subscribe();
...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]:不支持函数/类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!