Binding and notation in Angular 10
In the last episode of this series, I wrote about Angular Life Cycle Hooks. In the current post, I want to deep dive into Angular Databinding and the Databinding’s notation.
According to the official documentation of Angular, the data binding automatically keeps your page up-to-date based on your application’s state. You can bind data to specific things. Eg. source of an image, the state of a button, or data for a particular user.
There are several types of data binding. You can see the lists below.
- Interpolation
- Property
- Attribute
- Class
- Style
- Event
- Two-way
Interpolation
The purpose of the interpolation is to show values in the DOM. It refers to embedding expressions into marked-up text. By default, interpolation uses the double curly braces {{
and }}
as delimiters.
Property Binding
Property binding in Angular helps you set values for HTML element properties or directives. Some examples that you can make are toggle button functionality, set paths programmatically, and shared values between components. Brackets are the [ ] delimiters.
We can separate properties into three different subtypes.
Element property
<img [src]="heroImageUrl">
Component property
<app-hero-detail [hero]="currentHero"></app-hero-detail>
Directive property
<div [ngClass]="{'special': isSpecial}"></div>
Different Type Of Attributes Binding
Attribute Binding
Attribute binding in Angular helps you set values for attributes directly. You can improve accessibility, style your application dynamically, and manage multiple CSS classes or styles simultaneously.
It is recommended that you set an element property with a property binding whenever possible. However, sometimes you don’t have an element property to bind. In those situations, you can use attribute binding.
The attribute binding syntax
Attribute binding syntax resembles property binding, but instead of an element property between brackets, you precede the name of the attribute attr prefix
followed by a dot. Then, you set the attribute value with an expression that resolves to a string.
<p [attr.attribute-you-are-targeting]="expression"></p>
Class Attribute Binding
You can use class binding to add and remove CSS class names from an element’s class
attribute.
[class.sale]="onSale"
Style Attribute Binding
[style.width]="width"
Event Binding
Event binding allows you to listen for and respond to user actions such as keystrokes, mouse movements, clicks, and touches.
<button (click)="onSave()">Save</button>
Custom Events with Event Emitters
Event Emitters make the interaction smooth between the user and the directive.
In the following code snippet, the click event calls the delete method which is implemented in the TypeScript file.
// src/app/item-detail/item-detail.component.html (template)
<button (click)="delete()">Delete</button>
In the following code, the @Output decorator with our (Custom event) Event Emitter makes it possible to notify the parent component about any change. We send this notification about the change when the code calls the emit method of the EventEmitter in the delete function.
// src/app/item-detail/item-detail.component.ts (deleteRequest)
// This component makes a request but it can't actually delete a hero.
@Output() deleteRequest = new EventEmitter<Item>();
delete() {
this.deleteRequest.emit(this.item);
this.displayNone = this.displayNone ? '' : 'none';
this.lineThrough = this.lineThrough ? '' : 'line-through';
}
We define the deleteItem function below in the parent template. When our custom event emit function is triggered in the above code delete section. The deleteItem function will be called and the $event Object will be passed to the method.
<app-item-detail (deleteRequest)="deleteItem($event)" [item]="currentItem"></app-item-detail>
Two-Way DataBinding
Two-way binding gives components in your application a way to share data. Use two-way binding to listen for events and update values simultaneously between parent and child components.
When the user updates the serverName in the input field the onUpdateServerName is called automatically. In that function, the serverName property will get the new value. Due to the [(ngModel)]=”serverName” line that refers to the two-way data-binding, we will see the changes at once on the Front-End.
<label>Server Name</label>
<input
type="text"
class="form-control"
(input)="onUpdateServerName($event)">
<p>{{serverName}}</p>
<input
type="text"
class="form-control"
[(ngModel)]="serverName">
<!-- Square Brackets is the property binding notation -->
<!-- You can bind directives, own components, HTML attributes -->
<button
class="btn btn-primary"
[disabled]="!allowNewServers"
(click)="onCreateServer()">Add Servers</button>
<h4>String interpolation</h4>
<p style="color: red">{{allowNewServers}}</p>
<h4>Property Binding</h4>
<p [innerHTML]="allowNewServers" style="color: darkred"></p>
<p>{{serverCreationStatus}}</p>
export class ServersComponent implements OnInit {
allowNewServers = false;
serverCreationStatus = 'No Server was Created!';
serverName = '';
constructor() {
setTimeout(() => {
this.allowNewServers = true;
}, 2000);
}
onCreateServer = function(){
this.serverCreationStatus = 'Server was Created! Name is' + this.serverName;
};
// tslint:disable-next-line:typedef
onUpdateServerName(event: Event){
this.serverName = (event.target as HTMLInputElement).value;
}
ngOnInit(): void {
}
}
Conclusion
There are many different ways for data binding. Although, all of them are important the most useful is still the event binding. Event binding makes cross-communication between the components possible. I would say this is the spine of the components and directives communication.
Useful Links
Episodes
- First steps
- Modules
- Components
- View encapsulation
- Life Cycle Hooks
- Data bindings
- Services
- Directives
- Views
- Debugging