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

Angular2+:如何在非组件类中调用Provider?

这是个很典型的Angular场景问题哈~因为Item是普通的实体类,不是Angular的组件或可注入服务,所以没法直接通过构造函数注入ItemProvider。我给你几个实用的解决方案:

解决方案1:通过构造函数/方法传入ItemProvider实例

这是最推荐的方式,既保持了类之间的松耦合,也方便后续做单元测试。

方式A:创建Item实例时传入Provider

修改Item类的构造函数,接收ItemProvider作为参数并保存引用:

export class Item {
  private qtt: number;
  // 把ItemProvider注入到构造函数中
  constructor(qtt: number, private itemProvider: ItemProvider) {
    this.qtt = qtt;
  }
  add() {
    this.qtt++;
    // 直接调用Provider的add方法
    this.itemProvider.add(this.qtt);
  }
}

之后在需要创建Item实例的地方(比如组件里,已经注入了ItemProvider):

// 假设在组件中
constructor(private itemProvider: ItemProvider) {}

createAndUpdateItem() {
  // 创建Item时传入已注入的Provider实例
  const item = new Item(1, this.itemProvider);
  item.add();
}

方式B:调用add方法时临时传入Provider

如果不想在构造阶段就绑定Provider,也可以在调用add方法时传入:

export class Item {
  private qtt: number;
  constructor(qtt: number) {
    this.qtt = qtt;
  }
  add(itemProvider: ItemProvider) {
    this.qtt++;
    itemProvider.add(this.qtt);
  }
}

调用时的代码:

// 组件中
item.add(this.itemProvider);
解决方案2:把Item改为可注入服务(不推荐纯数据模型场景)

如果Item不只是单纯的数据模型,还包含较多业务逻辑,可以把它改成Angular服务,这样就能直接注入ItemProvider:

import { Injectable } from '@angular/core';
import { ItemProvider } from './item.provider';

@Injectable()
export class Item {
  private qtt: number;
  // 直接注入ItemProvider
  constructor(private itemProvider: ItemProvider) {
    this.qtt = 0; // 可以通过其他方法初始化数量
  }
  setInitialQtt(qtt: number) {
    this.qtt = qtt;
  }
  add() {
    this.qtt++;
    this.itemProvider.add(this.qtt);
  }
}

然后在组件中注入Item使用:

constructor(private item: Item) {
  item.setInitialQtt(1);
  item.add();
}

⚠️ 注意:这种方式只适合Item是单例业务对象的场景,如果需要创建多个独立的Item实例,就不适用了,因为Angular服务默认是单例的。

解决方案3:全局静态引用(非常不推荐)

可以把ItemProvider的实例保存到全局变量中,然后在Item类里直接调用,但这种方式会导致代码紧耦合,极不利于测试和维护,除非万不得已不要用:

// 在全局范围内声明一个变量保存Provider实例
export let GlobalItemProvider: ItemProvider;

// 在AppModule初始化时赋值
@NgModule({...})
export class AppModule {
  constructor(itemProvider: ItemProvider) {
    GlobalItemProvider = itemProvider;
  }
}

// 然后在Item类中使用
export class Item {
  private qtt: number;
  constructor(qtt: number) {
    this.qtt = qtt;
  }
  add() {
    this.qtt++;
    GlobalItemProvider?.add(this.qtt);
  }
}
总结

优先选解决方案1的方式,它遵循了依赖注入的设计原则,让Item类保持独立,方便后续的测试和扩展。如果Item只是纯数据模型,千万别把它改成服务,那样会混淆数据模型和业务服务的职责边界。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:09:29