Attribute Directives
Changing the appearance or behavior of an existing element with built-in directives like ngClass and your own custom ones.
2 phút đọc
Structural directives (@if, @for) change the shape of the DOM — adding, removing, repeating elements. Attribute directives don't add or remove anything; they change how an existing element looks or behaves, the way an HTML attribute would.
Built-in attribute directives
<div [ngClass]="{ active: isActive, disabled: isDisabled }">Item</div>
<div [ngStyle]="{ color: textColor, 'font-weight': isBold ? 'bold' : 'normal' }">
Styled text
</div>export class ItemComponent {
isActive = true;
isDisabled = false;
textColor = '#2563eb';
isBold = true;
}ngClass takes an object whose keys are class names and whose values are booleans — each class is applied only when its value is truthy. ngStyle does the same for individual CSS properties. For a single class, Angular's own class binding syntax is usually simpler than reaching for ngClass at all:
<div [class.active]="isActive">Item</div>Writing a custom attribute directive
A directive is a class decorated with @Directive instead of @Component — it has no template of its own, only behavior it attaches to whatever element it's placed on:
import { Directive, ElementRef, HostListener, inject } from '@angular/core';
@Directive({
selector: '[appHighlightOnHover]',
})
export class HighlightOnHoverDirective {
private el = inject(ElementRef);
@HostListener('mouseenter')
onMouseEnter(): void {
this.el.nativeElement.style.backgroundColor = '#fef3c7';
}
@HostListener('mouseleave')
onMouseLeave(): void {
this.el.nativeElement.style.backgroundColor = '';
}
}<p appHighlightOnHover>Hover over me.</p>ElementRef gives the directive a reference to the actual DOM node it's attached to, and @HostListener wires up event listeners on that node without needing (mouseenter) written out in every template that uses it. The selector [appHighlightOnHover] in square brackets means "match any element with this attribute" — the app prefix is just a naming convention to avoid colliding with real HTML attributes or a future browser feature.
Why bother with a directive instead of a service or a method
The point of an attribute directive is reuse: the hover-highlight behavior above works on any element, in any component, just by adding appHighlightOnHover to the tag — no method to define, no event binding to wire up, no duplication. Anywhere you find yourself copying the same (mouseenter)/(mouseleave) pair, or the same conditional class logic, across several templates, that's usually a sign it's worth extracting into a directive once instead of repeating it.