为什么 Angular 注入器检测到以下提供的,即使它不在注入器层次结构中?

Why does Angular injector detect the following provided even if its not in the injector heirarchy?

来自官方 docs,以下是启用 tree shaking 的 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

如果你去找@Contentchild装饰器的定义,它是写在原始文档中的:

The following selectors are supported.

  1. Any class with the @Component or @Directive decorator
  2. A template reference variable as a string (e.g. query <my-component #cmp> with @ContentChild('cmp'))
  3. Any provider defined in the child component tree of the current component (e.g. @ContentChild(SomeService) someService: SomeService)
  4. Any provider defined through a string token (e.g. @ContentChild('someToken') someTokenVal: any)
  5. A TemplateRef (e.g. query with @ContentChild(TemplateRef) template;)

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

编辑:docs reference