如何使用 Angular 中的依赖注入将属性指令实例传递给嵌套组件

Posted

技术标签:

【中文标题】如何使用 Angular 中的依赖注入将属性指令实例传递给嵌套组件【英文标题】:How to pass attribute Directive instance to nested component using Dependency Injection in Angular 【发布时间】:2020-11-14 22:10:34 【问题描述】:

我正在尝试使用属性指令将元素的模板引用从父组件传递到使用依赖注入的嵌套组件,但父组件中获取目标元素的指令实例不是被注入嵌套组件的同一个实例——正在创建指令的第二个实例,它不访问目标元素,这就是被注入的那个。

这是基本结构:

<div>
  <div #myTarget [appendTarget]="myTarget"></div>
  <child>
    <grandchild></grandchild>
  </child>
</div>

我正在尝试使用指令 appendTarget 和 DI 而不是 @Inputs(工作正常)将 #myTarget 的引用向下传递给 &lt;grandchild&gt;,因此 &lt;child&gt; 不需要知道它并充当传递者。

我已将AppendTargetDirective 包含在父组件的providers 数组中:

@Component(
  selector: 'app-root',
  templateUrl: './app.component.html',
  providers: [
    AppendTargetDirective
  ]
)
export class AppComponent 
  constructor()  

并将其注入&lt;grandchild&gt; 组件:

@Component(
  selector: 'grandchild',
  template: `
<div>
  Hi! Grandchild here...
</div>
  `
)
export class GrandchildComponent  
  constructor(
    private appendTargetDirective: AppendTargetDirective
  ) 

但是,有两个 AppendTargetDirective 实例正在创建,一个获取对 #myTarget 的引用,一个不获取,GrandchildComponent 获取后者。

Here's a StackBlitz 演示了这个问题。如果您打开控制台,您会看到 Directive 构造函数被调用了两次(我在其构造函数中为每个实例生成一个唯一 ID),并且获取目标元素的实例不是被注入的实例.我认为将它包含在父组件的 providers 数组中会创建一个它的单个实例,该实例将在父组件及其后代之间共享,但显然我的想法不正确。

任何帮助将不胜感激。

【问题讨论】:

【参考方案1】:

绝不不应该将 Angular 指令添加到 providers 数组。 Angular 会将它们视为服务,它们是指令类的独立实例,根本不依赖于模板结构。

以下是 Angular 在您的案例中尝试解决指令依赖的方式。

从当前元素开始往树上走

  3 ^  <div>
        <div #myTarget [appendTarget]="myTarget"></div>
  2 ^     <child>   
  1 ^       <grandchild></grandchild>
          </child>
       </div>

如果您将指令放在放置您孩子的 HTML 树的同一分支上,则指令的 DI 将起作用:

<div>
  <div #myTarget></div>
  <child [appendTarget]="myTarget">   <--------------------------- move it here
    <grandchild></grandchild>
  </child>
</div>

Forked Stackblitz

【讨论】:

以上是关于如何使用 Angular 中的依赖注入将属性指令实例传递给嵌套组件的主要内容,如果未能解决你的问题,请参考以下文章

Angular 1.5 组件依赖注入

Angular 指令依赖注入 - TypeScript

Angular2开发笔记

角度 6 依赖注入

在Angular2中,使用继承还是注入依赖?

Angular 2 - 如何将依赖项注入到自定义类中,该类不是组件并且不作为服务公开