On this page
Standalone components
Standalone components
In modern Angular (v17+), all components are standalone by default. You don't need NgModules to organize your application.
Anatomy of a component
A component has three parts:
- TypeScript class — The component's logic
- Template — The HTML view
- Styles — Encapsulated CSS
It is defined with the @Component decorator.
Component metadata
The @Component decorator receives an object with properties:
selector— The HTML tag nametemplate/templateUrl— The component's HTMLstyles/styleUrl— The component's CSSimports— Dependencies (other components, directives, pipes)changeDetection— Change detection strategy
Inputs and Outputs
Components communicate with their parents through:
input()— To receive data from the parentoutput()— To emit events to the parent
These replace the @Input and @Output decorators from previous versions.
// Required input
readonly name = input.required<string>();
// Input with default value
readonly role = input<string>('Student');
// Output (EventEmitter)
readonly selected = output<string>();Practice
- Create a card component: Build a
ProductCardcomponent with aninput()for the product name, another for the price, and anoutput()that emits when a "Buy" button is clicked. - Use the component from a parent: Import
ProductCardin another component and pass real data to it. Listen for the output event and log a message to the console. - Add OnPush: Ensure your component uses
ChangeDetectionStrategy.OnPushand verify it still works correctly.
In the next lesson, we will learn about Signals for managing state.
OnPush
Always use ChangeDetectionStrategy.OnPush. It improves performance by avoiding unnecessary template checks.
import { Component, input, output, ChangeDetectionStrategy } from '@angular/core';
@Component({
selector: 'app-user-card',
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<div class="card">
<h3>{{ name() }}</h3>
<p>{{ role() }}</p>
<button (click)="selected.emit(name())">Select</button>
</div>
`,
styles: `
.card {
padding: 1rem;
border: 1px solid var(--border-color);
border-radius: 0.75rem;
}
`,
})
export class UserCard {
readonly name = input.required<string>();
readonly role = input<string>('Student');
readonly selected = output<string>();
}
Sign in to track your progress