Event Binding
Parentheses bind a template event — a click, a keystroke, a form submission — to a method on the component class.
Handling a click
export class CounterComponent {
count = 0;
increment() {
this.count++;
}
}
<p>Count: {{ count }}</p>
<button (click)="increment()">+1</button>
Each click on the button calls increment(), which
updates count — and the {{ count }} display updates
automatically, with no manual DOM code required.(click)="increment()" reads as "when the click event fires, run increment()." Angular handles reflecting the changed count back into the template on its own.
Passing the event object
export class SearchComponent {
onKeyUp(event: KeyboardEvent) {
const input = event.target as HTMLInputElement;
console.log('Typed so far:', input.value);
}
}
<input (keyup)="onKeyUp($event)" placeholder="Search...">
Typed so far: h Typed so far: hi
$event is a special Angular template variable that always refers to whatever event object the handler was called with — here, the native browser KeyboardEvent, from which event.target gets you the actual input element.
Two-way binding revisited
Now that both halves are familiar, [(ngModel)]="query" from the previous lesson can be understood as sugar for exactly this pattern combined:
<input [ngModel]="query" (ngModelChange)="query = $event">
[ngModel]="query" is the property binding half (class → input), and (ngModelChange)="query = $event" is the event binding half (input → class). [( )] is just shorthand for writing both together.
increment() or onKeyUp(), runs inside the component's own this context automatically — you never need .bind(this) the way you sometimes do with plain JavaScript callbacks. Where people do get tripped up is passing a method as a bare reference instead of calling it, e.g. writing (click)="increment" without the parentheses — that does nothing, since it's not a valid event-binding expression rather than a call.