【问题标题】:Angular abstract class HttpClient injectionAngular 抽象类 HttpClient 注入
【发布时间】:2018-01-22 17:49:13
【问题描述】:

大家好,我是 Angular 的新手,我在使用 Injectable 类时遇到了麻烦。

我有一个抽象类(在 web.ts 上),它的受保护属性之一是 HttpClient 对象。这个抽象类的定义如下:

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);
}

然后我有另一个类(在 webA.ts 上)扩展了 Web 类:

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);
   }
}

最后,在我的网站的一个组件类中,我想将 WebA 实例化为:

private webA: Web = new WebA();

它告诉我需要在 webA.ts 中的 super("https://www.test.com"); 上传递一个 HttpClient 对象。为了解决这个问题,我可以为 WebA 创建如下构造函数:

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

但这会导致我做private webA: Web = new WebA(this.http); 强迫我拥有我的组件类:

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

我知道必须有另一种方法来做到这一点,因为在我看来这打破了我的班级的层次结构

TL;DR:
我需要在抽象类上“自动注入”一个 HttpClient,而不需要将此对象作为参数传递给扩展类中的 super。

【问题讨论】:

  • constructor(protected http: HttpClient) {} 应该可以解决问题

标签: angular httpclient injectable injectableprovider


【解决方案1】:

"auto-inject" 仅在您希望 DI 机制为您创建类型时才有效。在您的情况下,我认为最好将 WebA 类声明为可使用 @Injectable 注入,并在您需要它的类中注入 WebA 实例。这样HttpClient就会自动传递。

@Injectable()
export class WebA extends Web {

   ...

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

   ...

}

【讨论】:

    【解决方案2】:

    要么删除WebA中的构造函数

    export class WebA extends Web {
    
       //constructor() {
       //   super("https://www.test.com");
       //}
    

    或者重复构造函数参数并用super()转发

    export class WebA extends Web {
    
       constructor(baseURL: string, protected http: HttpClient) {
          super(baseURL, http);
       }
    

    如果您需要派生类中的构造函数 (WebA),唯一的方法是重复参数并转发它们。

    更新

    当您使用new Xxx() 创建实例时,没有自动注入这么简单。依赖注入仅适用于 Angulars DI 为您创建的实例。

    否则请参阅上面的答案。

    【讨论】:

    • 我认为他的问题是当他想create 实例时,他不想手动传递httpClient。嗨不注入WebA,而是手动创建
    • @SurenSrapyan 感谢您的提示。使用new ... 创建的类没有依赖注入。我更新了我的答案。
    • 这就是我想首先做的事情,但正如我所说,它打破了等级制度。有没有办法在 Web 抽象类上注入 HttpClient?我在 app.module.ts 上既没有 WebA 也没有 Web,因为它们不是我的应用程序的组件,只是辅助类。也许我可以通过将 HttpClient 添加到 app.module.ts 来制作 Angular 在 WebA 上注入 HttpClient??
    • 抽象类没有注入。正如我所提到的,只有 Angular 为您实例化的类注入,而 Angular 只实例化具体类。
    • @GünterZöchbauer 是的,我明白了...然后,我可以在 app.module.ts 上的declarations []providers [] 中的providers [] 中添加webA@NgModuleHttpClient?如果我这样做,它仍然说我仍然需要在 private webA: Web = new WebA(); 上传递 http 作为参数
    猜你喜欢
    • 1970-01-01
    • 2019-01-22
    • 2021-09-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多