Theory
How the class and the screen stay connected
An Angular component has two halves: the TypeScript CLASS (data and logic) and the HTML TEMPLATE (the view). They need to talk: the class's events array must appear in the template, a button click in the template must call a class method, a typed name must flow into a class property.
That connection is data binding, and Angular has exactly FOUR kinds, distinguished by direction and by a memorable bracket syntax. Master the four and you can wire any template to its class. Plus, you can write your own CUSTOM directives to add reusable behaviour to elements. This lesson is the glue of Angular.
At a glance
The four data bindings
| Binding | Syntax | Direction / job |
|---|---|---|
| Interpolation | {{ event.name }} | Class to view: display a value |
| Property binding | [disabled]="isFull" | Class to view: set an element property |
| Event binding | (click)="register()" | View to class: run a method on an action |
| Two-way binding | [(ngModel)]="name" | Both ways: keep field and property in sync |
Theory
The four, and the banana in a box
Three bindings are one-way; the fourth combines them:
- interpolation
{{ value }}: puts a class value into the view (text) - property binding
[prop]="value": sets an element's PROPERTY from the class ([disabled]="isFull") - event binding
(event)="method()": runs a class method when an event fires ((click)="register()") - two-way binding
[(ngModel)]="name": keeps a form field and a class property in sync BOTH directions
The two-way syntax [()] is nicknamed the 'banana in a box' (parentheses inside brackets), and it is literally property binding [] PLUS event binding () combined: it sets the field from the property AND updates the property when the field changes. It needs Angular's FormsModule.
Practical
All four bindings in a template
<!-- Interpolation: display a class value -->
<h2>{{ event.name }}</h2>
<!-- Property binding: set an element property from the class -->
<button [disabled]="seats === 0">Register</button>
<!-- Event binding: run a class method on click -->
<button (click)="register()">Confirm</button>
<!-- Two-way binding: field and class property stay in sync -->
<input [(ngModel)]="name">
<p>Hello, {{ name }}</p> <!-- updates live as you type -->
<!-- A CUSTOM attribute directive adding behaviour: -->
<p appHighlight>Featured event</p>
This example runs in Gri-Learn on the web, where you can edit it and see the output.
Theory
Two-way binding, and custom directives
The magic of [(ngModel)]="name" is that it does TWO things at once: it DISPLAYS the class's name in the input AND UPDATES name whenever you type. Type into the field and {{ name }} elsewhere changes instantly, no manual onChange needed.
Compare React: there you wired value={name} (property) AND onChange={e => setName(...)} (event) SEPARATELY, a controlled component. Angular's two-way binding BUNDLES those two into one [(ngModel)]. Same result, less code, at the cost of some 'magic'.
Custom directives let you package reusable element behaviour: a class decorated with @Directive (e.g. appHighlight) that you attach to any element to give it consistent behaviour, like the built-in directives but your own.
Quiz
What does Angular's two-way binding [(ngModel)]="name" do?
- Only displays name in the field (one-way)
- Keeps the input field and the class property 'name' in sync BOTH ways: the field shows name, and typing updates name
- Only updates name when a button is clicked
- Binds two different variables together
Show the answer
Keeps the input field and the class property 'name' in sync BOTH ways: the field shows name, and typing updates name
Two-way binding [(ngModel)]="name" synchronises the form field and the class property in BOTH directions: the input displays the current value of name, and typing in the input immediately updates name (which updates anywhere else name appears). It is literally property binding [ ] (class to view) plus event binding ( ) (view to class) combined, hence the [()] 'banana in a box'. Option A describes one-way interpolation/property binding only. Option C describes an event binding alone. Option D misreads it (it binds ONE property to a field, both ways). This bundles what React did with separate value + onChange into a single binding.
Think first
Angular's two-way vs React's controlled components
React needed value={name} AND onChange={e => setName(...)} for a form field. Angular does it with one [(ngModel)]="name". Which is 'better', and what is the trade-off? Then tap.
Show the answer
Neither is simply better; they trade convenience for explicitness. Angular's [(ngModel)] is more CONVENIENT: one binding does display-and-update, less code. React's controlled component is more EXPLICIT: you SEE both the value binding and the onChange update, so the data flow is fully visible and you control exactly what happens on each change (e.g. validate or transform mid-type). Angular hides that in 'magic' two-way sync; React keeps it manual and transparent. The design philosophies differ: Angular favours built-in convenience (it is a full framework), React favours explicit, predictable one-way flow (it is a minimal library). Knowing both, you can appreciate that two-way binding is really one-way property + one-way event combined, whichever framework spells it.
Watch out
Binding traps
Wrong bracket for the direction: {{}} display, [] property (in), () event (out), [()] two-way; the syntax encodes the direction.
ngModel without FormsModule: [(ngModel)] fails unless FormsModule is imported.
Confusing [prop] and (event): brackets set a property from the class; parentheses run a method on an event.
Overusing two-way binding: it is convenient but hides the data flow; reactive forms (next lessons) are often clearer for complex forms.
Custom directive naming: prefix custom directives (appHighlight) to avoid clashing with built-ins.
Theory
Binding done; now transform on display
You can bind data every direction between class and template. Often you want to TRANSFORM a value just for display, format a date, uppercase a title, show a currency, without changing the underlying data. Angular's PIPES do exactly that, and you can write custom ones. The next lesson covers built-in and custom pipes, then forms and services complete the Angular unit.
Summary
Key takeaways
- Data binding connects the component class and its template; Angular has four kinds.
- Interpolation {{ value }}: display a class value (class to view).
- Property binding [prop]="value": set an element property from the class (class to view).
- Event binding (event)="method()": run a class method on a user action (view to class).
- Two-way binding [(ngModel)]="x": keeps a field and property in sync both ways (property + event combined; needs FormsModule).
- Custom directives (@Directive) package reusable element behaviour, like your own attribute directives.
- Memory hook: {{}} shows, [] sets in, () sends out, [()] syncs both ways.