问题
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