Angular Components
Priority: P0 (CRITICAL)
Principles
- Standalone:
standalone: true. Import all dependencies directly inimportsarray. Do not declare in NgModule. (Angular 20+: standalone is the default —standalone: trueis not needed.) Useng generate cto scaffold automatically. - Signal Inputs: Use
input()and input.required<T>() instead of@Input(). Use booleanAttribute ornumberAttributetransforms where applicable (e.g.,input(false, { transform: booleanAttribute })). Access value as a function: this.disabled(). - Signal Outputs: Use output<T>() (from v17.3+) instead of
@Output() EventEmitter. Emit with: this.selected.emit(value). For two-way binding use model() which creates a writable signal. - Control Flow: Use @if (condition), @for (item of items; track item.id), @switch, and @empty { } blocks inside @for for empty state instead of
*ngIf,*ngFor. - Host Bindings: Define in the host: { } object on
@Component(e.g.,'[class.active]': 'isActive()','(click)': 'onClick()') — Never use @HostBinding or @HostListener decorators. - View Encapsulation: Default
Emulated. UseNonecarefully.
Signals Integration
- Use computed() for derived state and display values.
- Use
effect()strictly for side effects (logging, manual DOM manipulation), NEVER for state propagation. - Avoid logic in templates — move to
computed()or component methods. Set ChangeDetectionStrategy.OnPush.
Anti-Patterns
- No logic in template: Replace with
computed()signals or component method calls. - No ElementRef mutation: Encapsulate DOM changes in a Directive or use Renderer2.
- No class inheritance: Compose behavior using Directives and Services instead.