Angular v12与v14中@ContentChild支持InjectionToken的差异疑问
Angular 14中@ContentChild支持InjectionToken的说明及注入差异解析
1. 为什么Angular 14中@ContentChild可以用InjectionToken?
Angular 14对@ContentChild和@ContentChildren的选择器做了功能扩展,新增了对InjectionToken的支持。在v12及更早版本中,这两个装饰器仅支持组件/指令类、模板引用变量(字符串)作为选择器,因此v12中写法会报错,而v14能正常运行。该功能属于框架的隐性增强,官方文档可能存在更新滞后的情况。
2. @ContentChild能解析但构造函数注入不行的原因
核心差异在于依赖查找的注入器范围不同:
@ContentChild(WIDGET_TOKEN):当使用InjectionToken作为选择器时,Angular会在内容投影的子组件(VelocityWidgetComponent)自身的组件注入器中查找该令牌的提供者。由于你已在
VelocityWidgetComponent的providers数组里将WIDGET_TOKEN指向组件自身,Angular能在这个子组件的注入器中找到对应实例,成功赋值给widget属性。构造函数注入WIDGET_TOKEN:构造函数注入的依赖是从
WidgetWrapperComponent自身的注入器层级(包括其父组件、模块注入器)查找的。而WIDGET_TOKEN的提供者仅注册在VelocityWidgetComponent的组件注入器中,这个注入器属于内容投影的子组件,不在WidgetWrapperComponent的注入器查找链上,因此会抛出NullInjectorError。
相关代码回顾
定义令牌:
export const WIDGET_TOKEN = new InjectionToken("WIDGET_TOKEN")
子组件提供令牌:
@Component({ providers:[ {provide:WIDGET_TOKEN,useExisting:VelocityWidgetComponent} ] }) export class VelocityWidgetComponent implements OnInit {}
Wrapper组件获取内容子组件:
@Component({ styleUrls: ['./widget-wrapper.component.css'] }) export class WidgetWrapperComponent implements OnInit { @ContentChild(WIDGET_TOKEN,{static:true}) widget:any; }
内容的提问来源于stack exchange,提问作者sql_dummy
相关产品推荐
相关产品推荐

