#6: πŸ“₯ Property binding

We now have our input component, but it does not do much. We want to bring it to life.

Let's make the input control text reflect the value of the title property.

This is how our input component looks now:

input.component.ts
import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'todo-input',
  template: `
    <input>
    <button>Save</button>
    <p>The title is: {{ title }}</p>
  `,
  styleUrls: ['./input.component.css']
})
export class InputComponent implements OnInit {
  title: string = 'my title';

  constructor() {
    this.changeTitle('I love Angular');
  }

  ngOnInit() {
  }

  changeTitle(newTitle: string): void {
    this.title = newTitle;
  }

}

We use interpolation to present the value of the title property: {{ title }}

Angular then presents the value of title each time that our todo-input component is shown.

What if we want to show the title value inside the HTML input control itself?

Every input element has a property called value, which holds the string that is displayed inside the input box. In HTML, we can pass a string directly to the element's value attribute:

<input value="Hello World">

But we lose the dynamic binding between the properties in the controller and the template.

Angular lets us bind properties to the template easily and conveniently; we saw that with interpolation. Now we'll see how to bind to an element's property (not to be confused with class properties). We surround the wanted property with square brackets and pass it the class member:

<input [value]="title">

You can go on to the next chapter, but if you'd like to learn more about change detection, keep reading.

πŸ§ͺ Change Detection

Angular has a very efficient change detection mechanism. It looks for bindings in the components' templates, and then updates the value each time the bound expression is changed.

ngOnInit() {
  setTimeout(() => {
    this.title = 'This is not the title you are looking for';
  }, 3000);
}

setTimeout is a JavaScript function. Its first parameter is what we want to happen - a function of our choice. The second parameter is how much we want to delay it, in milliseconds. In this example, we pass an inline anonymous function which sets the value of this.title. For this we use one of the new features in JavaScript ES6: an arrow function.

Binding to Methods

The expressions that we can bind to in the template are not limited to class properties. They can be a method call or almost any other valid Angular template expression.

For example, let's bind the input value to a method call that returns a value. First, let's add the method generateTitle anywhere inside the class, but not inside any of its methods. The best practice is to have our custom methods under the lifecycle methods (ngOnInit, in this case).

generateTitle(): string {
  return 'This title was generated by a method.';
}

Replace one or both of the bindings of the title in the template with the method call (don't forget the parentheses!):

<input [value]="generateTitle()">
<button>Save</button>
<p>The title is: {{ generateTitle() }}</p>

So for now, we have our input control show the title of our todo in it. We now want to make the input change the value of the title back by entering a value in it and pressing Enter. How do we do that? Let's go to the next chapter and find out...

Resources

Angular Guide - Template Property Binding

A note about accessing the DOM

Using regular JavaScript, we can insert the value to the input via its properties. We'll fetch the element from the DOM and assign the value of the member title to the element's value property.

code for example
let inputElement = document.getElementById('my-input');
inputElement.value = this.title;

In JavaScript, we find the input element in the DOM by its id, and then set its value property to the value of the title property. We need to add the id to the input element then:

code for example
<input id="my-input">

This will work in the browser.

However, this is highly discouraged in Angular. You should never access the DOM directly! That's because you can assign different renderers to Angular and run the application on different platforms. They may be renderers for mobile, desktop, or even a robot. These platforms will not have a document object from which you can manipulate the result!

Last updated