angular - 指令和组件中本地提供者的优先级
问题描述
我认为指令的本地提供者是为其内容子项提供服务,例如:
//template in a module
<table>
<tr>
<td>{{ item.price | myPipe }}</td>
</tr>
</table>
myPipe
在其构造函数中具有依赖关系MyService
:
因此,如果我将指令定义为:
@Directive({
selector: "[myAttr]",
providers: [MyService]
})
export class MyDirective { }
并将其应用为:
<table>
<tr myAttr>
<td>{{ item.price | myPipe }}</td>
</tr>
</table>
那么MyService
inmyPipe
的构造函数就可以解决了。
但是如果有一个组件也在MyService
其本地提供者中定义并将其应用为:
<myComponent>
<tr myAttr>
<td>{{ item.price | myPipe }}</td>
</tr>
</myComponent>
既然两者都可以为 提供服务MyDirective
,那么将选择哪一个,本地提供者 还是?MyComponent
myPipe
myPipe
MyDirective
MyComponent
解决方案
前提
Angular 中的每个组件都有自己的 Injector 上下文,用于为其自身及其组件树提供服务(或更一般地说,Injectables)。
简短的回答
管道似乎总是使用它们所在模板的组件的 Injector 上下文(经过我的经验测试,需要引用)。parentComponent
因此,如果您有一个带有如下模板的组件(我们称之为它):
<myComponent>
<tr myAttr>
<td>{{ item.price | myPipe }}</td>
</tr>
</myComponent>
那么myPipe
将不会从任何一个myComponent
或myAttr
!因此,您的问题的直接答案不是!
相反,它将获得声明组件(即)使用(提供parentComponent
)的服务实例。
简短说明
就 HTML 结构而言,它确实似乎是和myPipe
的子级。然而,就 Angular 的层次结构而言,它是它的子级,因此它在那里获得了它的服务提供者。此外,与组件不同,管道不受内容投影的影响(使用)。myComponent
myAttr
myPipe
parentComponent
<ng-content>
还...
您对如何提供服务的理解似乎不太正确。以下是对您所做陈述的一些更正:
- “[I]如果我将指令定义为 (...) 并应用它 (...),则可以解析 myPipe 的构造函数中的 MyService” - 不正确,如我的回答所示。
- “如果有一个组件也在其本地提供程序中定义 MyService (...) MyDirective 和 MyComponent 都可以为 myPipe 提供服务” - 出于同样的原因,也不正确。
最后
组件的行为与管道不同。它们形成组件树,并且 Injector 上下文相应地发生变化。因此,如果代替myPipe
你有一个yetAnotherComponent
,它实际上会得到由提供的 MyService而myComponent
不是parentComponent
.
终于终于
如果您的指令提供服务并且您将该指令应用于组件,则该组件将获得指令提供的服务!当然,除非它自己注册了提供者。
推荐阅读
- azure-webjobs - 公开部署为 Web 作业的红隼服务器以进行外部交互
- python - Python SQLITE 更新子句未更新
- javascript - 如何使用javascript选择父母的兄弟姐妹的孩子(没有jquery)
- angular - 没有 BsModalService 提供者,我需要更改什么?
- html - HTML responsive navigation show first and last item always
- swift - 调用 ViewDidLoad 后立即使 Timer 开始计数
- c# - Specflow 场景在测试资源管理器中按字母顺序排序。有什么办法可以改变这个顺序?
- html - 从父母中排除孩子 svg mask-image
- c# - MVC 控制器操作/dll 仅适用于本地主机
- python - IndentationError:使用 Selenium 和 Python 抓取网页时出现意外缩进