You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular中如何不创建独立服务,直接使用ODataService实现组件API请求

问题(翻译自英文)

我有一个需要发起API请求的组件,同时存在一个用于此类服务的抽象类ODataService,其构造函数代码如下:

export class ODataService<T> extends ApiService {
  constructor(http: HttpClient, api: string) {
    super(http, null);
    this.servicePath = `odata/${api}`;
  }
}

该构造函数非空。我不想为单个组件的单个方法编写独立服务,因此考虑直接使用该抽象类为组件创建“一次性使用”的服务,尝试的实现代码如下:

@Component({
  selector: 'my-component',
  templateUrl: './my.component.html',
  changeDetection: ChangeDetectionStrategy.OnPush,
  providers: [{
    provide: 'myService',
    useFactory: (http) => new ODataService<IModel>(http, 'endpoint'),
    deps: [HttpClient]
  }]
})
export class MyComponent implements OnInit {
  @Input() entityId: string

  constructor(private myService: ODataService<IModel>) {
    super();
  }
}

但注入服务时出现错误:

This constructor was not compatible with Dependency Injection.

请问这种实现方式是否可行?


回答

这种实现思路完全可行,报错的核心原因是注入标识不匹配:你在组件的providers配置里用字符串'myService'作为服务的注入令牌,但组件构造函数里直接请求注入ODataService<IModel>类型,Angular的依赖注入系统找不到对应关联,才抛出构造函数不兼容的错误。

给你两种调整方案:

方案一:用泛型类作为注入令牌

直接把providers里的provide值改成ODataService<IModel>,和构造函数的注入类型保持一致:

@Component({
  selector: 'my-component',
  templateUrl: './my.component.html',
  changeDetection: ChangeDetectionStrategy.OnPush,
  providers: [{
    provide: ODataService<IModel>,
    useFactory: (http) => new ODataService<IModel>(http, 'endpoint'),
    deps: [HttpClient]
  }]
})
export class MyComponent implements OnInit {
  @Input() entityId: string

  constructor(private myService: ODataService<IModel>) {
    // 注意:如果组件没有继承其他Angular组件类,这里的super()要删掉,否则会报错
  }
}

方案二:保留字符串令牌,用@Inject指定

如果想继续用'myService'作为标识,需要在构造函数里用@Inject()装饰器明确指定注入令牌:

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

@Component({
  selector: 'my-component',
  templateUrl: './my.component.html',
  changeDetection: ChangeDetectionStrategy.OnPush,
  providers: [{
    provide: 'myService',
    useFactory: (http) => new ODataService<IModel>(http, 'endpoint'),
    deps: [HttpClient]
  }]
})
export class MyComponent implements OnInit {
  @Input() entityId: string

  constructor(@Inject('myService') private myService: ODataService<IModel>) {
  }
}

额外提醒

  • 你提到ODataService是抽象类,但给出的代码里它是可实例化的普通泛型类(没有abstract关键字),如果它确实是抽象类,要确保实例化时所有抽象方法都已实现,否则会报错。
  • 这种组件级注入的方式会让每个组件实例拥有独立的ODataService实例,正好符合你“一次性使用”的需求。

内容的提问来源于stack exchange,提问作者demo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 05:40:15