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

发布于 2025-01-11 22:53:04 字数 817 浏览 0 评论 0原文

来自官方文档,以下是轻量级注入令牌的示例 启用树摇动的模式:

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 呢?

From the official docs, following is an example of lightweight injection token pattern for enabling tree shaking:

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;
}

My question is that when Angular sees @ContentChild(LibHeaderToken), it will try to look for a provider with token name as LibHeaderToken, but it'll look for it on the current component or its parents (because its an hierarchical injector). It'll not look in LibHeaderComponent (which is where we have declared the required provider).

So why does this work and why LibHeaderComponent is also searched when looking for providers?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

人间☆小暴躁 2025-01-18 22:53:04

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

支持以下选择器。

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

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

编辑: 文档参考

If you look for the definition of @Contentchild decorator, it's written in the original docs:

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;)

In the bullet list, the 3rd bullet says "Any provider defined in the child component tree of the current component (e.g. @ContentChild(SomeService) someService: SomeService)". So in the example, LibCardHeader is in the child component tree of LibCardComponent, and the LibHeaderToken is a provider defined in the LibCardHeader -which is child component- which matches with the explanation "Any provider defined in the child component tree of the current component". The current component is LibCardComponent.

edit: docs reference

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文