Angular Components Output
Understanding the core of Angular
Introduction
Section titled “Introduction”Every Angular component must have:
- TypeScript class that describes the behaviors,
- HTML template that controls what renders into the DOM,
- CSS selector that defines how the component is used in HTML (optional, could also use a global).
You provide Angular-specific information for a component by adding the @Component decorator on top of the TypeScript class.
The object passed to the @Component decorator is called the component’s metadata.
@Component({ /* component's metadata */ selector: 'app-my-component', template: `<img src="profile-photo.jpg" alt="Your profile photo" />`, styles: ` img { border-radius: 50%; } `,})export class MyComponent {}Usually, HTML template and CSS classes are in a separate files:
import {Component, input} from '@angular/core';
@Component({ /* component's metadata */ selector: 'app-my-component', templateUrl: 'my-component.html', styleUrl: 'my-component.css',})export class MyComponent {}Use a component
Section titled “Use a component”To use a component, directive, or pipe, you must add it to the imports array in the @Component decorator:
import {Component, input} from '@angular/core';import {MyComponent} from './my-component';
@Component({ imports: [MyComponent], selector: 'app-out-component', template: ` <h1>Out Component</h1> <app-my-component><app-my-component /> `,})export class OutComponent {}Import MyComponent component in order to use it in OutComponent component’s template.
Custom events with outputs
Section titled “Custom events with outputs”Angular components can define custom events by assigning a property to the output function:
@Component({/*...*/})export class MyPanel { panelClosed = output<void>();}The above component is associated to the following template:
<expandable-panel (panelClosed)="savePanelState()" />The output function returns an OutputEmitterRef.
You can emit an event by calling emit() method on the OutputEmitterRef:
this.panelClosed.emit();Angular refers to properties initialized with output function as outputs. You can use outputs to raise custom events.
Angular custom events do not bubble up the DOM
When extending a component class, outputs are inherited by the child class. You can exclusively call output in component and directive property initializers.
Emitting event data
Section titled “Emitting event data”You can pass event data when calling emit:
// emit primitive values.this.valueChanged.emit(7);
// emit custom event objectsthis.thumbDropped.emit({ pointerX: 123, pointerY: 456,});When defining an event listener in a template, you can access the event data from the $event variable:
<my-slider (valueChanged)="logValue($event)" />Receive the event data in the parent component:
@Component({/*...*/})export class App { logValue(value: number) { /*...*/ }}Customizing output names
Section titled “Customizing output names”The output function accepts a parameter that lets you specify a different name for the event in a template:
@Component({/*...*/})export class CustomSlider { changed = output({alias: 'valueChanged'});}With the template:
<my-slider (valueChanged)="saveVolume()" />This alias does not affect usage of the property in TypeScript code.
While you should generally avoid aliasing outputs for components, this feature can be useful for renaming properties while preserving an alias for the original name or for avoiding collisions with the name of native DOM events.
Subscribing to outputs programmatically
Section titled “Subscribing to outputs programmatically”When creating a component dynamically, you can programmatically subscribe to output events from the component instance. OutputRef type includes a subscribe method:
const someComponentRef: ComponentRef<SomeComponent> = viewContainerRef.createComponent(/*...*/);
someComponentRef.instance.someEventProperty.subscribe((eventData) => { console.log(eventData);});Angular automatically cleans up event subscriptions when it destroys components with subscribers. Alternatively, you can manually unsubscribe from an event.
The subscribe function returns an OutputRefSubscription with an unsubscribe method:
const eventSubscription = someComponent.someEventProperty.subscribe((eventData) => { console.log(eventData);});
// ...
eventSubscription.unsubscribe();Event names
Section titled “Event names”Avoid choosing output names that collide with events on DOM elements like HTMLElement.
Name collisions introduce confusion about whether the bound property belongs to the component or the DOM element.
Avoid adding prefixes for component outputs like you would with component selectors. Since a given element can only host one component, any custom properties can be assumed to belong to the component.
Always use camelCase output names. Avoid prefixing output names with "on".
Declare outputs with @Output decorator
Section titled “Declare outputs with @Output decorator”You can alternatively define custom events by assigning a property to a new EventEmitter and adding @Output decorator:
@Component({/*...*/})export class MyPanel { @Output() panelClosed = new EventEmitter<void>();}You can emit an event by calling the emit method on the EventEmitter.
Aliases with the @Output decorator
Section titled “Aliases with the @Output decorator”@Output decorator accepts a parameter that lets you specify a different name for the event in a template:
@Component({/*...*/})export class MySlider { @Output('valueChanged') changed = new EventEmitter<number>();}The above component is associated to the following template:
<my-slider (valueChanged)="saveVolume()" />This alias does not affect usage of the property in TypeScript code.
Specify outputs in @Component decorator
Section titled “Specify outputs in @Component decorator”In addition to the @Output decorator, you can also specify a component’s outputs with the outputs property within @Component decorator.
This can be useful when a component inherits a property from a base class:
// `MySlider` inherits `valueChanged` property from `BaseSlider`.@Component({ /*...*/ outputs: ['valueChanged'],})export class MySlider extends BaseSlider {}You can additionally specify an output alias in the outputs list by putting the alias after a colon in the string:
// `CustomSlider` inherits the `valueChanged` property from `BaseSlider`.@Component({ /*...*/ outputs: ['valueChanged: volumeChanged'],})export class MySlider extends BaseSlider {}