Angular abstract class HttpClient injection

泪湿孤枕 提交于 2019-12-24 14:24:07

问题


Hi everyone, i'm new with Angular and I am having troubles with Injectable classes.

I have an abstract class (on web.ts) which one of its protected attributes is an HttpClient object. The definition of this abstract class is as follows:

import { HttpClient } from "@angular/common/http";


export abstract class Web {
   protected baseURL: string;

   constructor(baseURL: string, protected http: HttpClient) {
      this.baseURL =  baseURL;
   }

   public abstract RetrieveData(pattern: string);
}

Then I have another class (on webA.ts) which extends the Web class:

import { Web } from './web';

export class WebA extends Web {

   constructor() {
      super("https://www.test.com");
   }

   private Search(pattern: string) {
      pattern = pattern.replace(" ", "+");
      var searchURL = this.baseURL + `/site/searchpage.jsp?st=${pattern}&id=pcat17071`;

      console.log(searchURL);

      this.http.get(searchURL).subscribe(data => {
         console.log(data);
      });
   }

   public RetrieveData(pattern: string) {
      this.Search(pattern);
   }
}

Finally, in a class of a component for my website I want to instantiate WebA as:

private webA: Web = new WebA();

It tells me that I need to pass an HttpClient object on super("https://www.test.com"); in webA.ts. To fix it, I can make the constructor for WebA like:

constructor(@Inject(HttpClient) http: HttpClient) {
      super("https://www.test.com", http);
}

But this would lead me to do private webA: Web = new WebA(this.http); forcing me to have on my component class:

import { HttpClient } from "@angular/common/http";
...
constructor(private http: HttpClient) {}

I know there must be another way to do it because in my opinion this is breaking hierarchy on my classes

TL;DR:
I need to "auto-inject" an HttpClient on an abstract class to not to need passing this object as an argument on super in the extender class.


回答1:


"auto-inject" works only if you want the DI mechanism to create the type for you. In your case I think it is better to declare the class WebA as injectable with @Injectable and in your class, where you need it just inject WebA instance. This way the HttpClient will be passed automatically.

@Injectable()
export class WebA extends Web {

   ...

   constructor(private httpClient: HttpClient) {
      super("https://www.test.com", httpClient);
   }

   ...

}



回答2:


Either remove the constructor in WebA

export class WebA extends Web {

   //constructor() {
   //   super("https://www.test.com");
   //}

or repeat the constructor parameters and forward them with super()

export class WebA extends Web {

   constructor(baseURL: string, protected http: HttpClient) {
      super(baseURL, http);
   }

If you need a constructor in the derived class (WebA) the only way is to repeat the parameters and forward them.

Update

There is no such thin as auto-inject when you create an instance with new Xxx(). Dependency injection works only for instances that Angulars DI creates for you.

Otherwise see my answer above.



来源:https://stackoverflow.com/questions/48387445/angular-abstract-class-httpclient-injection

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!