How to write a correct Angular Component
Besides all-known and common patterns about how to create a component in Angular, there're some advanced patterns not everyone would tell or show you — not because nobody knows about them, but maybe some developers keep them as secrets. ;)
Make sure you always "display" it right
Even if you might not find it useful, sometimes it can give you some big trouble.
You could be in a situation where can't understand why some Component's children or either the current Component – is not showing or positioned as it needs to be, due to this - you can spend a lot of time searching for the problem, in the end, to find out that a simple display: block
can "save your life."
Just develop a behavior out of this, and always add :host { display: block; }
in component styles. It's not mandatory to be block
- this is just a typical case; change it as you need, but make sure you always apply it to your Component.
If you useng
to generate a component, there's a shortcut for that, add--displayBlock
option in your command, it should look like thisng generate component YourComponent --displayBlock
.
Add classes to host
There's another solution I came up with, keep reading ;)
With Web Components coming in, why not think about the Angular Component that's a simple div or another common element?
Do you have to add the class names to children's components, or you can bind them to the host and save space in the Component's HTML?
Or at least to have the HTML cleaner? It would help if you thought about it.
I always do this whenever I have a parent element that holds all component HTML, for example, if this is the Component's HTML:
I would rewrite it like this:
Thanks to the new Angular Directive composition API we can achieve this by injecting NgClass
inside hostDirective
.
Here's how it can be implemented:
In short, we tell Angular to add the NgClass
directive to the host, and inside the component we inject it and send the class names to be used to the host.
Make sure .parent
class is available outside of the component otherwise you won't see the .parent
styles.
I probably should add more NgClass
API explanation here, but this can make this article too big, so I might arrive with a new blog post clarifying NgClass
and (why not) NgStyle
in the future, keep an eye on me 👁️.
ChangeDetection to OnPush
Change detection is a cool feature in Angular, but you must be very attentive to it, as it can cause you significant issues. Why change it to OnPush? Simple, you don't need to recheck the Component's HTML every time something is changing inside the Parent Component.
But wait for a second, is it means Angular won't automatically check the Component's HTML for changes? Yes, it won't be. You must tell Angular when you should check the component changes, or use a straightforward trick — myVariable$ | async — let me explain to you more about it.
To mark the Component to be checked, a typical case is — to inject the ChangeDetectorRef class into the Component — ( I'm not going to show you how to achieve it here, check the official documentation page for more info. )
Another simple trick is to use Observables and Async pipe, remember I wrote an article about one of the best practices for sending HTTP requests in Angular – here's almost the same logic. Still, besides that, the async pipe automatically marks the Component to be checked for changes.
Let's see an example:
Hope you got the idea!
Angular CLI allows to change it automatically: ng generate component YourComponent --changeDetection=OnPush
Make use of exportAs metadata
exportAs metadata is another option that makes the Component looks more than advanced. With it, we can get, set, and call the Component's functions/variables outside the Component's scope. Thanks to the Angular Team ;)
For example, let's say we have a simple component:
Now, let's try to increase the count
outside the component scope:
Check this StackBlitz for a better example. Pay attention, we haven't used Angular @ViewChild
decorator to get the my-count
Component instance, and we just added some simple logic ONLY inside the template – That's awesome!
Now, imagine what you can do with CdkPortals and exportAs metadata! – no worry, I might create another article about it later on ;)
Thanks and see you in the next article, I'll leave here another article you might be interested in.