Angular component with varying appearance and click event
It seemed to be very simple: I wanted to create a component which displays a link and provides the ability to disable the link. Namely, disable the click event on the link and make it look disabled. So, how to handle the click event correctly in Angular?
Table of contents
Contents
In order to make the link disabled, I decided to convert it to a span. A few minutes later the component was created:
I thought it would be the easiest to display a span when the component is disabled and a link when it is enabled. Thus I filled in the component with code:
Then I created a sample application to test the new component:
Note: I'll soon be sharing short, practical tips on Angular — a good way to pick up something new if you're interested.
Piece of cake… Except it didn’t work:

Despite the conditions being alternatives, only the link worked – the span was hidden. I supposed there was a problem with disabled, so I started creating numerous variations on it, until I finally noticed the problem: the span element was displayed under correct conditions, but without any contents.
Why? Because you can’t use the same <ng-content> twice in a component. Only the first one will be filled with content, even if it is hidden. One of the solutions could look like this:
I put the <ng-content> only once, in a template, which I referenced twice from both span and link. This is one of the workarounds for referencing an ng-content in several places in a component.
That behavior is regrettably by design, and it is explained i.a. in this bug report. Please note that this trick cannot be used to display that ng-content more than one time in the component. I wrote about it in the consecutive post.
As you can see, now the contents is displayed correctly:

Click event
The next step was adding support for the click event. I added it in the component and handled in the application:
Here is the component:
And sample application:
Unfortunately, when testing the application, I discovered two new problems:
Button #1 was clicked Button #1 was clicked Button #2 was clicked Button #2 was clicked Button #3 was clicked
- although the
spandid not have theclickevent attached, that event (from the component) was fired when a user clicked the disabled link - clicking the enabled links raised two events
At first, I ignored double events and I thought that the solution found in Google Material’s source code (button.ts) will help for the first issue. I added _haltDisabledEvent() to the span:
It turned out that it helped for a real user using a web browser to not be able to fire the event, but a clever user could still click in the space around the label, still within the component. And it did not help for a unit test which checked if the component is clickable.
Another attempt also failed, even worse, as it did not prevent from clicking in any case:
Taking into consideration that even enabled component worked incorrectly (two events were fired), it led me to think that the initial approach was wrong. Probably the component should implement the ControlValueAccessor interface…
To be continued in future.
Lessons learned
Do not use two
<ng-content>Don’t implicitly declare all click events – some are handled automatically
Preventing clicking in a component is really tricky