如何让Angular的GrandChildComponent复用父组件与子组件的Service实例?
解决方案
问题根源
你在ChildComponent的providers数组中直接声明了Service,导致Child的注入器会强制创建新实例。即便你用@SkipSelf()让Child拿到了Parent的实例,但GrandChild会优先从Child的注入器获取Service(因为Child的providers里注册了该Service),从而得到新的实例。
修复步骤
替换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) {} }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
相关产品推荐
相关产品推荐

