In this article, we will delve into the world of Angular with Data binding. It is the basic knowledge that we must know when working with Angular.
So, let’s get started.
Table of contents
- One Way Binding : From Component to View
- One Way Binding : From View to Component
- Two way Binding
- Wrapping up
One Way Binding : From Component to View
In one way binding from Component to View, we have many different types such as:
-
Interpolation binding
It refers to binding expressions into marked up language.
// app.component.ts import { Component } from '@angular/core'; @Component({ selector: 'app-example', template: ` <div> '' </div>` }) export class AppComponent { authorName = 'Dan Brown'; }
-
Property binding
It is used to set a property of a View element by the value of a template expression that is stemed from the attributes of Component.
When we want to binding which property of View element, we should search or check this property is of that element correctly.
// app.component.ts import { Component } from '@angular/core'; @Component({ selector: 'app-example', template: `<input type='text' [disabled]='isDisabled' minLength=4 required >` }) export class AppComponent { isDisabled = false; }
The following is something that we need to avoid during property binding: https://www.pluralsight.com/guides/property-binding-angular
-
Attribute binding
It is used to set a
attribute
property of a View element. Attribute binding is mostly used where we do not have any property view wih respect to an html element attribute.For example:
<table> <tr> <td colspan='4'></td> </tr> </table>
The above code will throw an error Template parse errors: Can’t bindto ‘colspan’ since it isn’t a known native property.
The syntax of attribute binding:
[attr.attribute-name]='expression'
attribute-name
- the name of attribute that we wantexpression
- it will be evaluated to value forattribute-name
.For example:
// app.component.ts import { Component } from '@angular/core'; @Component({ selector: 'app-example', template: ` <table> <tr> <td [attr.colspan]='4'></td> </tr> </table> ` }) export class AppComponent { isDisabled = false; }
When working with attribute binding, we have the question about The difference between HTML attribute and DOM property. Below is the explannation about DOM properties and attributes HTML.
We can refer the link of angular.io.
When writing HTML source code, you can define attributes on your HTML elements. Then, once the browser parses your code, a corresponding DOM node will be created. This node is an object, and therefore it has properties.
For instance, this HTML element:
<input type="text" value="Name:">
has 2 attributes (
type
andvalue
).Once the browser parses this code, a
HTMLInputElement
object will be created, and this object will contain dozens of properties like:accept
,accessKey
,align
,alt
,attributes
,autofocus
,baseURI
,checked
,childElementCount
,childNodes
,children
,classList
,className
,clientHeight
, etc.For a given DOM node object, properties are the properties of that object, and attributes are the elements of the
attributes
property of that object.When a DOM node is created for a given HTML element, many of its properties relate to attributes with the same or similar names, but it’s not a one-to-one relationship. For instance, for this HTML element:
<input id="the-input" type="text" value="Name:">
The corresponding DOM node will have
id
,type
, andvalue
properties (among others):-
The
id
property is a reflected property for theid
attribute: Getting the property reads the attribute value, and setting the property writes the attribute value. id is a pure reflected property, it doesn’t modify or limit the value. -
The
type
property is a reflected property for thetype
attribute: Getting the property reads the attribute value, and setting the property writes the attribute value.type
isn’t a pure reflected property because it’s limited to known values (e.g., the valid types of an input). If you had<input type="foo">
, thentheInput.getAttribute("type")
gives you “foo” buttheInput.type
gives you “text”. -
In contrast, the
value
property doesn’t reflect thevalue
attribute. Instead, it’s the current value of the input. When the user manually changes the value of the input box, thevalue
property will reflect this change. So if the user inputs John into the input box, then:theInput.value // returns "John"
whereas:
theInput.getAttribute('value') // returns "Name:"
The
value
property reflects the current text-content inside the input box, whereas thevalue
attribute contains the initial text-content of thevalue
attribute from the HTML source code.So if you want to know what’s currently inside the text-box, read the
property
. If you, however, want to know what the initial value of the text-box was, read theattribute
. Or you can use thedefaultValue
property, which is a pure reflection of the value attribute:theInput.value // returns "John" theInput.getAttribute('value') // returns "Name:" theInput.defaultValue // returns "Name:"
There are several properties that directly reflect their attribute (
rel
,id
), some are direct reflections with slightly-different names (htmlFor
reflects thefor
attribute,className
reflects theclass
attribute), many that reflect their attribute but with restrictions/modifications (src
,href
,disabled
,multiple
), and so on. The spec covers the various kinds of reflection.
-
-
Class binding
It is used to set a
class
property of a View element with CSS classes. If we use javascript for this functionality, we will useremoveClass()
oraddClass()
dynamically.Syntax:
[class.className]='expression'
class
- the property of a View element.className
- then name of class that we want to apply for this element.expression
- it will be evaluated totrue
orfalse
to determine if the class should be applied.For example:
<div [class.alert-danger]='isDanger'> ... </div>
When we use
class.className
in our applicatin, it uses only one class name for a View element. So, if we want to apply multiple class name for it. What will we do?–>
ngClass
directive will be applied in this case.ngClass
should receive an object with class names as keys and expressions that evaluate totrue
orfalse
as values.For example:
// app.component.ts import { Component } from '@angular/core'; @Component({ selector: 'app-example', template: ` <div [ngClass]='classes'> ... </div> <div [ngClass]='setClasses()'> ... </div> ` }) export class AppComponent { ... classes = { alert-danger: this.isDanger, inactive: !this.isActive, ... }; setClasses() { let classes = { alert-danger: this.isDanger, inactive: !this.isActive, ... }; return classes; } }
-
Style binding
It is used to set a
style
of a View element. Sometimes, we want to set the property that has the unit such as em, px, % or rem.<button [style.width.px]="'120'">Browse</button> <button [style.font-size.em]="isDanger ? '20' : '10'">Take care</button>
// app.component.ts import { Component } from '@angular/core'; @Component({ selector: 'app-example', template: `<div [style.color]='color'></div>` }) export class AppComponent { color = '#333'; authorName = 'Dan Brown'; }
Like the class binding, we also want to set multiple style for a View element, we can use
ngStyle
directive to do it.// app.component.ts import { Component } from '@angular/core'; @Component({ selector: 'app-example', template: ` <button [ngStyle]='multipleStyles'>Click me!</button> <button [ngStyle]='getStyles()'>Cancel</button> ` }) export class AppComponent { multipleStyles = { 'background-color': 'red', 'foreground-color': 'white', 'font-size': '20px', 'width': '120px', 'height': '30px' } getStyles() { 'background-color': 'white', 'foreground-color': 'cyan', 'font-size': '20px', 'width': '120px', 'height': '30px' } }
One Way Binding : From View to Component
In one way binding from view to component, we can use event binding to implement it.
-
Event binding
For example:
// app.component.ts import { Component } from '@angular/core'; @Component({ selector: 'app-example', template: `<button (click)='displayContent()'> Click me! <button>` }) export class AppComponent { displayContent(): void { ... } }
So, when we click the above button,
displayContent()
method in the Componenet will be called.Some notes about event binding:
-
The event binding is composed by a target event surrounded by parentheses equals to an expression to be executed when that event is fired.
-
Each event binding will have information about the event, you can access to this information through the event object:
$event
. -
If the event is a native DOM event, then the event object will have the same info as any native DOM event
-
There are three types of events:
Element event
,Component event
andDirective Event
.<!-- Element event --> <button (click) = "onSave()">Save</button> <!-- Component event --> <hero-detail (deleteRequest)="deleteHero()"></hero-detail> <!-- Directive event --> <div (myClick)="clicked=$event">click me</div>
-
Two way Binding
We can use ngModel
directive to implement two way binding.
For example:
// In app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from "@angular/forms";
import { AppComponent } from './app.component';
import { FormsModule } from "@angular/forms";
@NgModule({
imports: [BrowserModule, FormsModule],
declarations: [ AppComponent],
bootstrap: [AppComponent]
})
export class AppModule { }
// In app.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-example',
template: `
<input [(ngModel)] ='val'>
Entered value is:
`
})
export class AppComponent {
val: string = 'Hello, angular 7';
}
The first thing to use ngModel
is to import FormsModule
from @angular/forms
in app.module.ts
file.
If we do not import the FormsModule, we will get error like Template parse errors.
But, we can wonder that What is the nature of two way binding with ngModel?
In fact, two-way binding is the combination of property binding and event binding. We can do this with the below example:
<!-- earlier version -->
<input [value]="username" (input)="username = $event.target.value" />
<p>Hello </p>
<!-- latest version -->
<input [ngModel]="name" (ngModelChange)="name = $event" />
With the earlier version, we have:
-
[value]="username"
- binds the expressionusername
to the input element’svalue
property. -
(input)="expression
- is a declarative way of binding an expression to the input element’sinput
event. -
username=$event.target.value
- the expression that gets executed when theinput
event is fired. -
$event
- is an expression exposed in event bindings by Angular, which has the value of the event’s payload. The payload of the input event is an InputEventObject which comes with a target property, which is a reference to the DOM object that fired the event.
With the latest version, we have:
-
The property binding
[ngModel]="name"
takes care of updating the underlying input DOM element. -
The event binding
[(ngModelChange)]
notifies the outside world when there was a change in the DOM. Then,[(ngModelChange)]
takes care of extractingtarget.value
from the inner$event
payload and simply emits that.Actually, the DefaulValueAccessor will take care of extracting that value and also writing to the underlying DOM object.
Wrapping up
-
The image below will have overview about data binding in Angular.
-
ngModel
comes as a built-in directive as part of theFormsModule
to implement two-way binding and should be preferred when building components that serve as custom form controls. -
Unlike AngularJS, Angular does not provide two way binding by default, which avoid all the digest cycle and watchers issues that AngularJS dealt with.
-
Data binding in Angular works by synchronizing the data in the components with the UI so that it reflects the current value of the data. To achieve the synchronization of the View and the Model, Angular uses change detection.
Refer:
https://www.pluralsight.com/guides/property-binding-angular
https://www.pluralsight.com/guides/attribute-class-style-bindings-angular
https://www.pluralsight.com/guides/one-and-two-way-data-binding-angular
https://blog.thoughtram.io/angular/2016/10/13/two-way-data-binding-in-angular-2.html
https://medium.com/@bartsis/understanding-two-way-data-binding-in-angular-2-a8eafa850637
https://medium.com/@preethi.s/angular-custom-two-way-data-binding-3e618309d6c7