1

来自官方文档lightweight injection token,以下是启用摇树模式的示例:

abstract class LibHeaderToken {}

@Component({
  selector: 'lib-header',
  providers: [
    {provide: LibHeaderToken, useExisting: LibHeaderComponent}
  ]
  ...,
})
class LibHeaderComponent extends LibHeaderToken {}

@Component({
  selector: 'lib-card',
  ...,
})
class LibCardComponent {
  @ContentChild(LibHeaderToken) header: LibHeaderToken|null = null;
}

我的问题是,当 Angular 看到 时@ContentChild(LibHeaderToken),它会尝试查找令牌名称为的提供程序LibHeaderToken,但它会在当前组件或其父组件上查找它(因为它是一个分层注入器)。它不会查看LibHeaderComponent(这是我们声明所需提供程序的地方)。

那么为什么这行得通,为什么LibHeaderComponent在寻找提供者时也会被搜索呢?

4

1 回答 1

1

如果您查找@Contentchild装饰器的定义,它会写在原始文档中:

支持以下选择器。

  1. 任何带有 @Component 或 @Directive 装饰器的类
  2. 作为字符串的模板引用变量(例如,使用 @ContentChild('cmp') 查询 <my-component #cmp>)
  3. 当前组件的子组件树中定义的任何提供者(例如@ContentChild(SomeService) someService: SomeService)
  4. 通过字符串标记定义的任何提供者(例如 @ContentChild('someToken') someTokenVal: any)
  5. 一个 TemplateRef(例如使用 @ContentChild(TemplateRef) 模板查询;)

在项目符号列表中,第 3 个项目符号表示“在当前组件的子组件树中定义的任何提供程序(例如 @ContentChild(SomeService) someService: SomeService)”。因此,在示例中,LibCardHeader位于 LibCardComponent 的子组件树中,而LibHeaderToken是定义在 LibCardHeader 中的提供程序-是子组件 - 与“当前组件的子组件树中定义的任何提供程序”的解释相匹配. 当前组件是LibCardComponent

编辑:文档参考

于 2022-03-04T06:58:48.963 回答