我试图手动注入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不需要异步初始化.
@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] 举报,一经查实,本站将立刻删除。