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

如何让@Input传入模板内的组件访问宿主组件提供的服务

解决方案

核心思路是手动指定ngTemplateOutlet使用宿主组件的注入器来渲染传入的模板,Angular为ngTemplateOutlet提供了ngTemplateOutletInjector输入参数专门处理这类注入器上下文切换的场景。

步骤1:在宿主组件中注入Injector

修改HostComponent的代码,注入Angular的Injector实例:

import { Component, Input, TemplateRef, Injector } from '@angular/core';
import { MyService } from './my.service';

@Component({
  selector: 'app-host',
  templateUrl: './host.component.html',
  providers: [MyService],
})
export class HostComponent {
  @Input()
  template: TemplateRef<any>;

  constructor(public injector: Injector) {}
}

步骤2:给ngTemplateOutlet指定注入器

修改HostComponent的模板,传入injector参数:

<ng-container 
  [ngTemplateOutlet]="template" 
  [ngTemplateOutletInjector]="injector"
></ng-container>

修改完成后,<app-item-element>在渲染时就会使用HostComponent的注入器解析依赖,成功拿到MyService的实例。

提示:ngTemplateOutletInjector为Angular 14及以上版本提供的API,如果使用低于14的版本,可以通过ViewContainerRef.createEmbeddedView(templateRef, context, injector)手动渲染模板,传入宿主的injector即可实现相同效果。


可选替代方案(适配特殊场景)

如果不方便修改宿主组件的注入逻辑,也可以通过模板上下文传递服务实例,侵入性稍高,需要修改两处代码:

  • 宿主组件传递服务实例到模板上下文:
<ng-container 
  [ngTemplateOutlet]="template"
  [ngTemplateOutletContext]="{myService: myService}"
></ng-container>

需要先在宿主组件构造函数中注入MyService实例,存为公共属性。

  • 使用模板时显式接收并传递服务:
<ng-template #item let-service="myService">
  <app-item-element [myService]="service"></app-item-element>
</ng-template>

同时需要修改ItemElementComponent添加对应输入属性接收服务实例。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 06:06:08