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

How to pass attribute Directive instance to nested component using Dependency Injection in Angular

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

这是基本结构:

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

我正在尝试使用指令 appendTarget 和 DI 而不是 @Inputs(工作正常)将对 #myTarget 的引用向下传递到 <grandchild> 所以 <child>不需要知道它并充当传递。

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

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

并将其注入到 <grandchild> 组件中:

@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 数组中会创建它的单个实例,该实例将在父组件及其后代之间共享,但显然我的想法不正确。

如有任何帮助,我们将不胜感激。

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

以下是 Angular 尝试解决您的情况下的指令依赖性的方法。

从当前元素开始往树上走

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

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

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

Forked Stackblitz