【问题标题】:Angular DI providers vs viewProvidersAngular DI 提供者与 viewProviders
【发布时间】:2020-09-28 01:22:57
【问题描述】:

我正在尝试了解 Angular 的 DI 框架并参考https://angular.io/guide/hierarchical-dependency-injection 中的官方文档;特别是 viewProviders 和 providers 属性之间的区别。

虽然我不能说内容很容易理解(尤其是它解释了它如何使用组合逻辑树并在 <#VIEW> 中使用符号 @Provide@Inject 的部分有时在组件的选择器标签中),我得出结论,使用 viewProviders 而不是提供程序会影响使用 <ng-content> 的投影内容的呈现@

谈到这个问题,如果 在提供程序和 viewProviders 中都使用相同的 DI 令牌,我看不到对场景的解释。

例如。

参考 parent.component.ts 中的 sn-p,我的问题是:如果通过取消注释 providers 属性能够呈现元素注入器中配置的值“world”,而不是模块注入器中的值“hello”,为什么忽略值“angular”?

viewProviders: [{ provide: Service, useValue: { value: 'world' } }],
  // providers: [{ provide: Service , useValue: { value: 'angular' } }], // If I uncomment this line the "hello" changes to "world" and the value "angular" is disregarded

https://stackblitz.com/edit/angular-syh4mx

这可能不是一个有效的用例,但我有兴趣了解它为什么会这样。

【问题讨论】:

    标签: angular dependency-injection


    【解决方案1】:

    基于此documentation,您将价值注入最近的注入器。如果您已注释掉提供程序,则关闭注入器是全局注入器,并且如果其未注释的最近注入器位于组件上。

    这有点像一个错误,因为直觉上的全局注入器也没有viewProvider 重要,并且当provider 不存在时,它的行为应该类似。但正如您在unit test 中看到的那样,它的预期行为定义了在同时定义providersviewProviders 时它的行为方式。您可以在section的末尾找到您问题的确切答案

    <app-root @NgModule(AppModule)
            @Inject(FlowerService) flower=>"?">
      <#VIEW>
        <p>Emoji from FlowerService: {{flower.emoji}} (?)</p>
        <app-child @Provide(FlowerService="?")
                   @Inject(FlowerService)=>"?"> <!-- search ends here -->
          <#VIEW> <!-- search starts here -->
            <h2>Parent Component</h2>
            <p>Emoji from FlowerService: {{flower.emoji}} (?)</p>
          </#VIEW>
         </app-child>   </#VIEW> </app-root>
    

    当请求 FlowerService 时,注入器开始它的 搜索属于 ( 的 因为它是从@Component()) 注入的,并以 .

    结尾

    被包括在内,因为它是从 @Component() 注入的,所以就像如果 providers 是注释的一部分,那么它的触发器包括作为查找列表一部分的视图并在查找列表首先检查 viewProviders 中的值。

    您可以找到与此行为相关的代码here

    【讨论】:

    • 感谢您的研究。请问,你是如何推断“如果提供者是注释的一部分,那么它的触发器包括作为查找列表一部分的视图”。是基于你对代码的理解吗?文档没有明确说明。
    • 另外,当您说“并且在查找列表上查看视图首先检查 viewProviders 中的值”时,如果我将 sn-p 修改为如下viewProviders: [{ provide: Service }], providers: [{ provide: Service , useValue: { value: 'angular' } }],,您将如何解释该行为@ 通过相同的逻辑,不应该选择“棱角分明”吗?当我在 stackblitz 中尝试时,服务未定义,html 输出为 projection:
    • 此外,如果我修改如下://viewProviders: [{ provide: Service }], providers: [{ provide: Service , useValue: { value: 'angular' } }], 输出是 angular projection: angular 这是有道理的,但我希望前面的场景也有相同的输出
    • 1.我主要从我从代码中链接的文档部分中得到这个。实际上很难从代码中推断出这一点,因为组件上使用的注释装饰器之间存在很多关系。我找不到处理该特定行为的确切位置。但是从代码中我看到渲染逻辑要求对通过注释提供的元数据声明的依赖项。这加粗的句子是我脑海中触发的原因,为什么它可以正常工作。
    • 2 和 3。如果你写 viewProviders: [{ provide: Service }] 它是未定义的,因为你将 Service 声明为未定义,你必须编写其中任何一个才能将其声明为:viewProviders: [Service]viewProviders: [{ provide: Service, useClass: Service }]跨度>
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-06-12
    • 2013-02-06
    • 2018-08-21
    • 1970-01-01
    • 2019-12-01
    • 2019-12-02
    • 2019-12-01
    相关资源
    最近更新 更多