指令和组件中本地提供者的优先级

5 angular-directive angular

我认为指令的本地提供者是为其子内容提供服务,例如:

//template in a module 
<table>
   <tr>
      <td>{{ item.price | myPipe }}</td>    
   </tr>
</table>
Run Code Online (Sandbox Code Playgroud)

myPipe在其构造函数中具有依赖项MyService

因此,如果我将指令定义为:

@Directive({
    selector: "[myAttr]", 
    providers: [MyService]
})
export class MyDirective { }
Run Code Online (Sandbox Code Playgroud)

并将其应用为:

<table>
   <tr myAttr>
      <td>{{ item.price | myPipe }}</td>    
   </tr>
</table>
Run Code Online (Sandbox Code Playgroud)

那么MyServiceinmyPipe的构造函数就可以解决了。

但是,如果有一个组件也在MyService其本地提供程序中定义并将其应用为:

<myComponent>
   <tr myAttr>
      <td>{{ item.price | myPipe }}</td>    
   </tr>
</myComponent>
Run Code Online (Sandbox Code Playgroud)

由于 和MyDirective都可以为MyComponent提供服务myPipe,那么会选择哪一个myPipe,本地提供商 MyDirectiveMyComponent

Avi*_*ius 0

前提

Angular 中的每个组件都有自己的注入器上下文,用于为其自身及其组件树提供服务(或更一般地说,可注入)。

简短回答

管道似乎总是使用它们所在模板的组件的注入器上下文(由我凭经验测试,需要引用)。因此,如果您有一个组件(我们称之为parentComponent),其模板如下所示:

<myComponent>
   <tr myAttr>
      <td>{{ item.price | myPipe }}</td>    
   </tr>
</myComponent>
Run Code Online (Sandbox Code Playgroud)

那么myPipe不会myComponent从或获取服务实例myAttr!所以你的问题的直接答案不是

相反,它将获取声明组件(即)使用(提供parentComponent)的服务实例。

简短说明

就 HTML 结构而言,它确实似乎是和myPipe的子级。然而,就 Angular 的层次结构而言,它是 的子级,因此它的服务提供者在那里。此外,与组件不同,管道不受内容投影(使用)的影响。myComponentmyAttr myPipeparentComponent<ng-content>

还...

看来您对如何提供服务的理解不太正确。以下是对您所作陈述的一些更正:

  1. “[I]如果我将指令定义为 (...) 并应用它 (...),则可以解析 myPipe 构造函数中的 MyService” - 不正确,如我的答案所示。
  2. “如果有一个组件也在其本地提供程序中定义了 MyService(...),则 MyDirective 和 MyComponent 都可以为 myPipe 提供服务” - 出于同样的原因,也不正确。

最后

组件的行为与管道不同。它们形成组件树,并且注入器上下文相应地改变。因此,如果myPipe您有一个yetAnotherComponent,它实际上myComponent获得由 提供的 MyService ,而不是parentComponent.

终于终于

如果您的指令提供服务并且您将该指令应用于组件,则该组件将获得该指令提供的服务!当然,除非它自己注册了一个提供商。