Angular中能否将AppSomeLogic注入到ng-content传入的AppChild组件?
问题:通过ng-content投影的组件能否注入外层嵌套的父组件?
场景复现
parent.component.html(选择器:app-parent)
<div class="parent"> <app-some-logic> <ng-content></ng-content> </app-some-logic> </div>
app.component.html
<app-parent> <app-child></app-child> </app-parent>
报错代码(AppChild组件)
@Component({ selector: 'app-child', standalone: true, imports: [], ... }) export class AppChild { constructor(parent: AppSomeLogic) { super(parent); } }
答案
不能直接这样注入。核心原因是:Angular的依赖注入是看组件的声明层级,不是渲染后的DOM层级。
AppChild是在AppComponent的模板里声明的,它的注入上下文属于AppComponent(以及更上层的注入器),哪怕通过ng-content把它的DOM投影到了AppSomeLogic内部,组件的注入上下文不会跟着DOM移动。所以Angular找不到AppSomeLogic实例,会抛出注入错误。
如果要让AppChild拿到AppSomeLogic的实例,有两种常用方案:
方案1:用@Input传递实例
在AppParent的模板里给AppSomeLogic加模板引用,把实例通过投影内容传递给AppChild:
<!-- parent.component.html --> <div class="parent"> <app-some-logic #someLogic> <ng-content [someLogic]="someLogic"></ng-content> </app-some-logic> </div>
<!-- app.component.html --> <app-parent> <app-child [someLogic]="someLogic"></app-child> </app-parent>
然后在AppChild里定义输入属性接收:
@Component({...}) export class AppChild { @Input() someLogic!: AppSomeLogic; }
方案2:用InjectionToken提供实例
先定义一个注入令牌,在AppSomeLogic组件里把自身实例绑定到这个令牌上:
// 定义全局注入令牌 export const SOME_LOGIC_TOKEN = new InjectionToken<AppSomeLogic>('SOME_LOGIC_TOKEN');
// AppSomeLogic组件 @Component({ selector: 'app-some-logic', providers: [{ provide: SOME_LOGIC_TOKEN, useExisting: AppSomeLogic // 把自身实例作为令牌的值提供 }], ... }) export class AppSomeLogic {}
然后在AppChild里通过这个令牌注入,建议加上@Optional()避免投影范围外的报错:
@Component({...}) export class AppChild { constructor( @Optional() @Inject(SOME_LOGIC_TOKEN) private someLogic?: AppSomeLogic ) {} }
内容的提问来源于stack exchange,提问作者mvermand
相关产品推荐
相关产品推荐

