Modern Angular 04: Component Templates and Interaction
This is lesson 4 of the Modern Angular Course. In the previous lesson, we created our first standalone component and rendered it using its selector. Now that we understand the structure of a component, it is time to make it interactive.
This post is part of the Modern Angular Course series. Check the course page for the full episode list.
In this post, we cover:
- How Angular templates define what users see
- How to display data with interpolation
- How to bind properties to HTML attributes
- How to handle user events
- How to combine bindings to build interactive components
Templates Are Where Components Come Alive
A component class defines behavior, but the template defines what users actually see. This is where Angular connects your data to the DOM.
Angular templates are:
- Declarative — you describe what the UI should look like, not how to update it
- Predictable — data flows in one direction, from the component to the template
- Explicit about data flow — every binding is visible in the markup
Once you understand templates, Angular becomes much easier to reason about.
Interpolation: Displaying Data
The simplest form of binding is interpolation. It lets you display component data directly in the template.
In the component class, add a property:
1
protected title = 'Welcome to Modern Angular!';
Notice the protected keyword. In modern Angular, the Angular style guide recommends using protected for properties and methods that are only used in the template. This makes the intent clear: protected members are accessible to the template but not to other components or services. If a property is only needed inside the component class itself, use private instead.
This also affects how we test the component. Since protected members are not accessible from the test file, we need to test them through the template instead of accessing properties directly. This is actually a good practice — it encourages testing the component the way users interact with it. We will cover this in detail later in the course, but if you want to learn more now, check out Angular v21 Template Coverage Testing.
Now display it in the template using double curly braces:
1
<h1></h1>
This is one-way data flow: the component owns the data, and the template renders it. Angular keeps the DOM in sync automatically — when the property changes, the template updates.
Property Binding
Next, let’s look at property binding. Instead of hardcoding values in HTML, we bind them from the component.
In the component class, add a property:
1
protected isDisabled = false;
Now bind it to an HTML attribute using square brackets:
1
<button [disabled]="isDisabled">Toggle</button>
The square bracket syntax [disabled] tells Angular to evaluate isDisabled as an expression and bind the result to the disabled property of the button element. Property binding allows the component to control the UI in a clear and explicit way.
Event Binding
Now let’s handle user interaction. Angular uses event binding with parentheses for this.
Add a method to the component class:
1
2
3
4
protected onClick() {
console.log('Button clicked');
this.isDisabled = !this.isDisabled;
}
Then bind it to a click event in the template:
1
<button (click)="onClick()">Toggle</button>
The parentheses syntax (click) tells Angular to listen for the click event and call onClick() when it fires. This is how user actions flow back into your component logic.
Combining Bindings
Most real components combine multiple bindings. Here is the full template for our Hello component with interpolation, property binding, and event binding working together:
1
2
3
4
5
6
<p>This is my first Angular component!</p>
<h1></h1>
<button [disabled]="isDisabled"
(click)="onClick()">Toggle</button>
And the complete component class:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import { Component } from '@angular/core';
@Component({
selector: 'app-hello',
imports: [],
templateUrl: './hello.html',
styleUrl: './hello.scss',
})
export class Hello {
protected title = 'Welcome to Modern Angular!';
protected isDisabled = false;
protected onClick() {
console.log('Button clicked');
this.isDisabled = !this.isDisabled;
}
}
Notice what happens when you click the button: the component state changes, and Angular updates the UI automatically. You do not manually touch the DOM. You do not force re-renders. Angular handles it for you.
Updating the View
This is the core Angular mental model for interaction:
- The component owns the state (properties like
titleandisDisabled) - The template binds to that state (interpolation and property binding)
- User actions update the state (event binding)
- Angular updates the DOM automatically
There is no manual DOM manipulation. There are no imperative update calls. You change the data, and the template reflects the change.
Template Readability Matters
One important tip: keep templates readable.
Avoid:
- Complex expressions in templates
- Business logic inside HTML
- Long chains of method calls in bindings
Use templates to describe what the UI should look like, and components to describe how things work. This separation makes your code easier to test and maintain as the application grows.
Source Code
The full source code for the course is available on GitHub: loiane/modern-angular.
Next Step
In the next lesson, we introduce signals — the foundation of state management in modern Angular. We will see how signals simplify state updates, make data flow clearer, and improve readability. That is where modern Angular really starts to shine.
Watch the Video
This post is part of the Modern Angular Course series. Check the course page for the full episode list.
