Rens Jaspers
Posted on January 27, 2024
When we build Angular apps, sometimes our components do too much. Take an AppComponent
, for instance, that's burdened with tasks like changing the page title, receiving app updates, logging the app version, and tracking user clicks. These functions, though important, don't align with the component's main role of displaying content. As a result, AppComponent
becomes crowded and complex, deviating from its primary purpose. This is where Angular's directives help. They are a simple solution that makes it easier to handle these tasks.
Directives in Angular allow us to neatly separate these side tasks from the component's core functionalities. By assigning responsibilities like click tracking and logging to directives, we prevent the main component from becoming overwhelmed. This leads to a cleaner, more focused AppComponent
that sticks to displaying and interacting with content. Directives keep our apps organized, making them simpler and easier to handle.
Example of a 'Do Everything Component':
import { Component, OnInit, HostListener } from '@angular/core';
import { TitleService } from './title.service';
import { UpdateService } from './update.service';
import { VersionLoggerService } from './version-logger.service';
import { ClickTrackingService } from './click-tracking.service';
@Component({
selector: 'app-root',
template: `...`,
// ...
})
export class AppComponent implements OnInit {
constructor(
// Ugh, so many injected services!
private titleService: TitleService,
private updateService: UpdateService,
private versionLoggerService: VersionLoggerService,
private clickTrackingService: ClickTrackingService
) {}
ngOnInit() {
// Updating the title
this.titleService.updateTitle('App Title');
// Subscribing to app updates
this.updateService.getAppUpdates().subscribe(update => {
// Handle update logic
});
// Logging the app version
this.versionLoggerService.logVersion();
// Other unrelated behaviors can also be added here
}
@HostListener('click', ['$event'])
trackClick(event: Event) {
this.clickTrackingService.trackClick(event);
}
}
Now lets create some directives to help us move these extra jobs out of our component. We can make a special directive for each job, like one for changing the page title and another for tracking clicks. This keeps our components simple and focused on their main job.
// update-title.directive.ts
import { Directive, OnInit } from '@angular/core';
import { TitleService } from './title.service';
@Directive({
selector: '[updateTitle]',
})
export class UpdateTitleDirective implements OnInit {
constructor(private titleService: TitleService) { }
ngOnInit() {
this.titleService.updateTitle('New Title');
}
}
// click-track.directive.ts
import { Directive, HostListener } from '@angular/core';
import { ClickTrackingService } from './click-tracking.service';
@Directive({
selector: '[appClickTrack]',
})
export class ClickTrackDirective {
constructor(private clickTrackingService: ClickTrackingService) {}
@HostListener('click', ['$event'])
onHostClick(event: MouseEvent): void {
this.clickTrackingService.trackClick(event);
}
}
As you can see, each directive handles one job. This makes them easier to work with and check. For instance, the directive for changing the page title does just that. It keeps its job separate from the rest of the app's code.
Adding these directives to our components is easy. We use hostDirectives
in the @Component
part to put in our new directives. Now, AppComponent
is more about showing content and less about doing many different jobs.
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
template: `...`,
hostDirectives: [UpdateTitleDirective, AppUpdateAlertDirective, LogVersionDirective, ClickTrackDirective] // Put your host directives here!
})
export class AppComponent {
// AppComponent focuses on its template-related logic only
}
In the end, using directives in Angular for tasks that don't deal with showing content is a really good idea. It makes our components simpler and less full of different tasks. Building and maintaining our app becomes easier. The components stay focused on their main job – showing things to users. Using directives this way keeps our app neat and easy to work with.
Posted on January 27, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.