如何在静态方法或自定义类中注入HttpClient?

elz*_*zoy 11 inject typescript angular

我想HttpClient在静态方法或类中使用angular (在类中它不能被定义为构造函数参数).

我尝试过类似的东西:

export class SomeNotInjectableService {
  static doSomething() {
    const injector = Injector.create({
      providers: [{provide: HttpClient, deps:[]}]
    });
    const httpClient: HttpClient = injector.get(HttpClient);

    httpClient.request(...); // error Cannot read property 'handle' of undefined
  }
}
Run Code Online (Sandbox Code Playgroud)

这是尝试在静态服务方法中手动注入客户端.不行.我很好奇如何做到这一点或如何在普通方法中注入客户端,但在一个不是组件的类中.

Dav*_*vid 16

我不确定它是否按照您尝试的方式工作(可能在您创建注射器时缺少某些东西),但如果您使用"注入"注射器,它会起作用

如果您查看抛出错误的代码,您会看到它提到请求的处理程序,在您的示例中似乎为null.当HttpClient以"传统"方式提供时,也许angular会注册一些内部处理程序,但不是你做的方式

//从Observable.of()开始初始化请求,并在concatMap()中运行处理程序(//包括所有拦截器).这样,处理程序在一个Observable链中运行//,这会导致在每个//订阅上重新运行拦截器(这也会使重试重新运行处理程序,包括拦截器).

    var /** @type {?} */ events$ = rxjs_operator_concatMap.concatMap.call(rxjs_observable_of.of(req), function (req) { return _this.handler.handle(req); });
Run Code Online (Sandbox Code Playgroud)

解决方法:

app.module.ts

import {Injector} from '@angular/core';

export let InjectorInstance: Injector;

export class AppModule 
{
  constructor(private injector: Injector) 
  {
    InjectorInstance = this.injector;
  }
}
Run Code Online (Sandbox Code Playgroud)

你的静态类/方法

import {InjectorInstance} from './app.module';

export class SomeNotInjectableService {
  static doSomething() 
  {
  /*  const injector = Injector.create({
      providers: [{provide: HttpClient, deps:[]}]
    });
    const httpClient: HttpClient = injector.get(HttpClient);
*/
    const httpClient =  InjectorInstance.get<HttpClient>(HttpClient);

    httpClient.request(...)...
  }
}
Run Code Online (Sandbox Code Playgroud)

Stackblitz上的示例:https://stackblitz.com/edit/angular-li8b37 file = app%2Fapp.component.ts

  • 这是唯一的解决方案吗?如果我想将其编写为独立库并避免在任何组件/服务中声明任何内容怎么办?这只是一个例子。你的解决方案让我非常满意,但也许还有另一种选择。 (2认同)

And*_*tar 15

如果您没有注射器,也可以跳过注射器.这意味着自己做"注射".我不建议这样做.如果你真的想使用静态方法(支持适当的服务),请传递所有需要的东西.

我不确定这是否已经很明显,但是这个httpClient管道中将缺少任何HTTP拦截器,因为没有办法解决它们.

import { HttpClient, HttpXhrBackend } from '@angular/common/http';

const httpClient = new HttpClient(new HttpXhrBackend({ build: () => new XMLHttpRequest() }));
httpClient.get('test').subscribe(r => console.log(r));
Run Code Online (Sandbox Code Playgroud)

或使用您自己创建的注射器(如果您不喜欢传递ctor args):

const injector = Injector.create({
    providers: [
        { provide: HttpClient, deps: [HttpHandler] },
        { provide: HttpHandler, useValue: new HttpXhrBackend({ build: () => new XMLHttpRequest }) },
    ],
});
const httpClient: HttpClient = injector.get(HttpClient);
httpClient.get('test').subscribe(r => console.log(r));
Run Code Online (Sandbox Code Playgroud)