Skip to content

hostDirectives should auto-resolve double matchingΒ #57846

@waterplea

Description

@waterplea

Which @angular/* package(s) are relevant/related to the feature request?

core

Description

I have been using hostDirectives extensively for past several months and NG0309: Directives can only match an element once. error is the bane of my existence and a huge burden on Directive Composition API.

I have heard an argument from the Angular team that order of execution matters in case multiple directives have host binding to the same property. I don't believe this reasoning makes any sense when it comes to directives because it's literally impossible to maintain anyway and even if it was β€” it's a terrible practice to rely on <div dirA dirB> behaving differently than <div dirB dirA>.

Consider this situation:
All my buttons have a host directive that applies some visual rules β€” appearance.
All my dropdown items have the same host directive.

Now imagine I have an element, say a sidebar item, that can be both a dropdown item and a button and needs some code from both of those directives. If I add both button and dropdown item to host directives of sidebar item I get appearance double matched.

Collapsed sidebar shows items in dropdown:
image

Expanded sidebar shows them outside of dropdown as regular buttons:
image

I tried to make this example as simple and transparent as possible to illustrate the issue, please do not take it at face value. In reality this cases are much more complex, but they boil down to this:

We need to be able to declare host directives freely without having to worry about combining our directives further down the line and finding out some particular combinations cause errors due to nested host directives structure.

There's an added complexity here because host directive declarations can expose different inputs/outputs, so the real discussion here should be how to handle those best. But the core idea that it shouldn't throw for multiple matches is absolutely clear, unless I'm missing something which I'm sure I'm not but if you have a good reasoning for it β€” please bring it up.

Proposed solution

Once a directive is already matched on an element, ignore all subsequent matches like providers do when they are seen multiple times in providers arrays of multiple directives on the same element.

Alternatives considered

None possible

Metadata

Metadata

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions