Two-Way Binding with ngModel
Keeping a template and a component property in sync in both directions with ngModel and the banana-in-a-box syntax.
2 phút đọc
Property binding ([value]) pushes data from the class into the template. Event binding ((input)) sends it back the other way. Two-way binding does both at once, with a single piece of syntax, for the common case of an input that should stay in sync with a variable as the user types.
The syntax
<input [(ngModel)]="searchTerm" placeholder="Search..." />
<p>Searching for: {{ searchTerm }}</p>import { Component } from '@angular/core';
import { FormsModule } from '@angular/forms';
@Component({
selector: 'app-search-box',
imports: [FormsModule],
template: `
<input [(ngModel)]="searchTerm" placeholder="Search..." />
<p>Searching for: {{ searchTerm }}</p>
`,
})
export class SearchBoxComponent {
searchTerm = '';
}The square brackets and parentheses together — nicknamed "banana in a box" for how [()] looks — mean this is both a property binding and an event binding at once. Typing into the input updates searchTerm, and if searchTerm changes some other way (say, a "clear" button resets it to ''), the input's displayed value updates too.
ngModel isn't built into Angular's core; it comes from FormsModule, which is why it needs to be added to the component's imports array before [(ngModel)] will work — a common first error is forgetting this import and getting a template parse error about an unknown property.
What it desugars to
[(ngModel)]="searchTerm" is shorthand for writing the property and event bindings out separately:
<input [ngModel]="searchTerm" (ngModelChange)="searchTerm = $event" />Seeing it unrolled like this makes clear that two-way binding isn't magic — it's Angular's convention that a directive named x paired with an output named xChange can be combined into [(x)]. You can apply this same pattern to your own components' @Input/@Output pairs, which you'll see in the next section of this course.
Where this fits
[(ngModel)] is the fastest way to wire up a simple form field, and it's the foundation of what Angular calls template-driven forms, covered later in this course. For forms with real validation rules, dynamic fields, or values that need to be checked before submission, Angular also offers reactive forms, which manage form state in the component class instead of the template. Both are valid — which one to reach for depends on how much control the form needs, and you'll see the trade-offs directly once both are introduced.