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

如何让Angular的GrandChildComponent复用父组件与子组件的Service实例?

解决方案

问题根源

你在ChildComponent的providers数组中直接声明了Service,导致Child的注入器会强制创建新实例。即便你用@SkipSelf()让Child拿到了Parent的实例,但GrandChild会优先从Child的注入器获取Service(因为Child的providers里注册了该Service),从而得到新的实例。

修复步骤

  1. 替换ChildComponent的Service提供方式
    移除ChildComponent中直接在providers里声明的Service,改用工厂提供者实现「优先复用父级实例,无则创建自身实例」的逻辑:

    @Component({
      selector: 'app-child',
      templateUrl: './child.component.html',
      providers: [
        {
          provide: MyService,
          useFactory: (parentService: MyService) => parentService || new MyService(),
          deps: [[new Optional(), new SkipSelf(), MyService]]
        }
      ]
    })
    export class ChildComponent {
      constructor(public service: MyService) {}
    }
    
  2. GrandChildComponent无需修改
    直接注入Service即可,它会从Child的注入器获取实例,自然和Child使用同一个:

    export class GrandChildComponent {
      constructor(public service: MyService) {}
    }
    

逻辑说明

  • useFactory会先通过deps配置尝试从父级注入器获取Service实例:
    • 如果父级(比如ParentComponent)提供了Service,就复用该实例;
    • 如果父级没有提供,则创建一个新的MyService实例。
  • GrandChildComponent作为Child的子组件,注入时会优先从Child的注入器获取Service,因此必然和Child使用同一个实例。
  • 若ParentComponent提供了Service,那么Parent、Child、GrandChild三者会共用Parent的实例;若Parent未提供,Child和GrandChild共用Child创建的实例。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 17:05:12