Я думаю, что локальный поставщик директивы должен предоставлять услуги для своих дочерних элементов, например:
//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
в конструкторе myPipe
может быть разрешено.
Но если есть компонент, также определите MyService
в его локальных провайдерах и примените его как:
<myComponent>
<tr myAttr>
<td>{{ item.price | myPipe }}</td>
</tr>
</myComponent>
поскольку и MyDirective
, и MyComponent
могут предоставлять услуги для myPipe
, так что myPipe
выберет местный поставщик MyDirective
или MyComponent
?
Каждый компонент в Angular получает свой собственный контекст инжектора, который используется для предоставления услуг (или, в более общем смысле, инъекций) себе и своему дереву компонентов.
Кажется, что каналы всегда используют контекст Injector компонента, в шаблоне которого они находятся (эмпирически проверено мной, ссылка необходима). Итак, если у вас есть компонент (назовем его parentComponent
) с шаблоном, который выглядит так:
<myComponent>
<tr myAttr>
<td>{{ item.price | myPipe }}</td>
</tr>
</myComponent>
тогда myPipe
не получит экземпляр службы ни от myComponent
, ни от myAttr
! Так что прямой ответ на ваш вопрос - ни то, ни другое!
Вместо этого он получит экземпляр службы, используемый (предоставленный) объявляющим компонентом (т. е. parentComponent
).
С точки зрения структуры HTML действительно кажется, что myPipe
является потомком как myComponent
, так и myAttr
. Однако с точки зрения иерархии Angular myPipe
является дочерним элементом parentComponent
, поэтому он получает там своего поставщика услуг. Кроме того, на каналы, в отличие от компонентов, не влияет проекция контента (использование <ng-content>
).
Похоже, ваше понимание того, как предоставляются услуги, не совсем верно. Вот некоторые исправления сделанных вами заявлений:
Компоненты ведут себя иначе, чем трубы. Они формируют деревья компонентов, и соответственно изменяются контексты Injector. Таким образом, если вместо myPipe
у вас есть yetAnotherComponent
, он фактически получит MyService, предоставляемый myComponent
, а не parentComponent
.
Если ваша директива предоставляет Службу и вы применяете эту Директиву к Компоненту, этот Компонент получит Службу в соответствии с Директивой! Если, конечно, он сам не зарегистрировал провайдера.
Хороший вопрос по очень запутанной теме. См. мой ответ, который, надеюсь, освещает практические аспекты проблемы в вашем конкретном случае. К сожалению, подробное объяснение было бы очень сложно написать, и оно соответствовало бы собственной документации Angular, которую я рекомендую вам прочитать: angular.io/guide/… и angular.io/guide/hierarchical. -внедрение-зависимости. Кроме того, в случае подобных неопределенностей, один из лучших способов сделать это - попробовать различные сценарии, что я и сделал - вы можете точно увидеть, как все это работает.