Angular provides a powerful mechanism for a wide range of bindings. You don’t have to be new to forget which binding is which. Sometimes, when reaching for the right binding, I mess up or forget the syntax. I thought an article might help clarify how and when to apply bindings in your Angular applications, for those memory moments we all sometimes have.

Below is a handy-dandy chart for quick reference (linked to each section):

Binding Example
Property Binding <input [placeholder]="placeholderValue" />
String Interpolation <input placeholder="{{placeholderValue}}" />
Attribute Binding <td [attr.colspan]="clspn">
Style Binding <input [style.borderStyle]="'dashed'" />
Class Binding <input [class.active]="true" />
Event Binding <input (keyup.enter)="onEnter()" />
Two-way Binding <input [(ngModel)]="value" />

It includes all of the types of Angular Bindings along with a line of markup showing how that binding can be used. We'll cover all the bindings in more detail in the sections below, except for attribute binding, which I found to be quite uncommon.

Property Binding

In Angular, the simplest binding is property binding. It uses `[ ]` brackets to get the job done. It is a one-way binding from the component to the template. 

<input [placeholder]="placeholderValue" />

String Interpolation vs Property Binding

You can also use string interpolation to get the same property binding done:

<input placeholder="{{placeholderValue}}" />

String interpolation is best suited for text between opening and closing elements:


This same approach can be done through property binding but it's less intuitive. In the example above, we can achieve the same result through the textContent attribute:

<h2 [textContent]="amazingTitle"></h2>

Ultimately, it comes down to personal preference. Buttons in Kendo UI take advantage of different property binding types in order to give you the ability to customize the look of our buttons. For example, you can set [icon] to any number of icons (found here). You can also set the [look] of the button to outline, flat, or default! You can read more about the awesome customizable Kendo UI button here.

<button kendoButton [icon]="'folder'" [look]="'outline'">{{btnValue}}</button>

Here, we are using string interpolation to bind the value of the button. At the same time, we're using property bindings for its icon and look. It's important to mention that both binding types are one-way bindings; from the component to the template. You'll have to use discretion for which type of binding you use. Again, it comes down to personal preference.

Style Binding

Another type of property binding is style binding. We can add styles inline with logic! If we’d like to apply some inline styles to this button we can do so inside the square brackets:

<button kendoButton ... [style.backgroundColor]="'rebeccaPurple'"></button>

In the example above, we've changed the background color to rebeccaPurple, but any CSS-acceptable color value (HEX, RGB, etc) will work. Check W3Schools for a full list of DOM style properties you can bind to.

Let's now look at the same example but with some logic:

<button kendoButton ... [style.backgroundColor]="isActive ? 'rebeccaPurple' : 'white'"></button>

Here, we are binding the background color to rebeccaPurple only if the isActive variable is true. Otherwise, the background color is set to white.

So style binding is just property binding to style [style.PROPERTY] followed by the property you'd like to modify.

You can play around with style bindings in this StackBlitz!

Class Binding

The last version of property binding is class binding. This is very similar to style binding; instead of muddying up our template with inline styles, you add an active class to an element and handle the styling in an associated stylesheet. In the following example, we are applying the active class based on the state of isActive in the component:

<button kendoButton ... [class.active]="isActive"></button>
/* styles.css */

.k-button.active {
  background-color: rebeccaPurple;
  color: white;

The .k-button class is used for specificity and would not be needed in all cases.

Event Binding

Our button is pretty snazzy, however we need to actually be setting/unsetting the isActive variable. We can use event binding to capture a variety of user-initiated events and initiate logic in our component class. Angular supports many kinds of events. If we'd like to catch the click event on our button and bind it to a method, we can do so, using parentheses:


Here, we are binding the toggleActive method to be called on button click. The toggleActive method is just setting the active variable to !active. Then we are using the class binding to give our button an active class. The button will be rebeccaPurple when active and grey when not. We also set these changes to happen on hover when active: .k-button.active:hover.

/* styles.css */

.k-button.active, .k-button.active:hover {
  background-color: rebeccaPurple;
  color: white;
// app.component.ts

<button kendoButton

Can download from: http://cl.nicoll.co/1ac444ccc7aa

Two-way Binding

So far, we've examined the various ways to establish unidirectional or one-way bindings. Another type of binding is a bidirectional or two-way binding. Two-way bindings are used when a developer wishes to propagate changes made to an underlying value or event between a component and its template.

In Angular, we can use ngModel to create that two-way data binding. Let's use the same example we built earlier with Kendo UI. First, we have to import the FormsModule in order to have access to ngModule:

Can download from http://cl.nicoll.co/05b4e2285e16

Next, we need to include Kendo UI inputs for this example:

Can download from http://cl.nicoll.co/e1351c3f2ab5

Now, we are ready to establish a two-way binding:

import { Component } from '@angular/core';

  selector: 'my-app',
  template: `<input kendoTextBox [value]="email" (keyup.enter)="onEnter()" />`

export class AppComponent {
  email = "bob@gmail.com";
  // ...
  onEnter() {

Here, we are using the property binding to bind the value of this kendoTextBox to email. The keyup.enter event is bound to the onEnter() method that displays the email entered by the user. Unfortunately, when we change the <input> element and hit enter, the alert is not updated. What is going on?

Download link: http://cl.nicoll.co/8b0e3d615e75

In this example, the property binding, which as you recall, is a one-way binding (only FROM the component TO the template). We need to use a two-way binding! This is where the formsModule comes in. We'll use the ngModel for two-way binding, which comes from the formsModule:

<input kendoTextBox [(ngModel)]="email" (keyup.enter)="onEnter()" />

Now, instead of a one-way binding, we are two-way binding with [(ngModel)]. For this we are going to need to use both the square brackets and parentheses [()]. The email value now changes in the displayed alert. 🙂 It works! It works!

Download from http://cl.nicoll.co/c7d427cead95

Recap the Bindings

To recap, one-way bindings use the [] square brackets for property, style, and class bindings. For event bindings, we need to use parentheses () and for two-way binding, we use both [()] square brackets and parentheses!

Binding Example
Property Binding <input [placeholder]="placeholderValue" />
String Interpolation <input placeholder="{{placeholderValue}}" />
Attribute Binding <td [attr.colspan]="clspn">
Style Binding <input [style.borderStyle]="'dashed'" />
Class Binding <input [class.active]="" />
Event Binding <input (keyup.enter)="onEnter()" />
Two-way Binding <input [(ngModel)]="value" />


I hope you've enjoyed this binding party and never get them mixed up again! Here are some extra links to docs about the components used above. Happy coding!


About the Author

Alyssa Nicoll

Alyssa is an Angular Developer Advocate & GDE. Her two degrees (Web Design & Development and Psychology) feed her speaking career. She has spoken at over 30 conferences internationally, specializing in motivational soft talks, enjoys gaming on Xbox and scuba diving in her spare time. Her DM is always open, come talk sometime.

Related Posts


Comments are disabled in preview mode.