How Change Detection Works

Let's see how change detection works with a simple example.

We are going to create a simple MovieApp to show information about one movie. This app is going to consist of only two components: the MovieComponent that shows information about the movie and the AppComponent which holds a reference to the movie with buttons to perform some actions.

Our AppComponent will have three properties: the slogan of the app, the title of the movie and the lead actor. The last two properties will be passed to the MovieComponent element referenced in the template.

app/app.component.ts

import {Component} from '@angular/core';
import {MovieComponent} from './movie.component';
import {Actor} from './actor.model';

@Component({
  selector: 'app-root',
  template: `
    <h1>MovieApp</h1>
    <p>{{ slogan }}</p>
    <button type="button" (click)="changeActorProperties()">
      Change Actor Properties
    </button>
    <button type="button" (click)="changeActorObject()">
      Change Actor Object
    </button>
    <app-movie [title]="title" [actor]="actor"></app-movie>`
})
export class AppComponent {
  slogan = 'Just movie information';
  title = 'Terminator 1';
  actor = new Actor('Arnold', 'Schwarzenegger');

  changeActorProperties() {
    this.actor.firstName = 'Nicholas';
    this.actor.lastName = 'Cage';
  }

  changeActorObject() {
    this.actor = new Actor('Bruce', 'Willis');
  }
}

In the above code snippet, we can see that our component defines two buttons that trigger different methods. The changeActorProperties will update the lead actor of the movie by directly changing the properties of the actor object. In contrast, the method changeActorObject will change the information of the actor by creating a completely new instance of the Actor class.

The Actor model is pretty straightforward, it is just a class that defines the firstName and the lastName of an actor.

app/actor.model.ts

export class Actor {
  constructor(
    public firstName: string,
    public lastName: string) {}
}

Finally, the MovieComponent shows the information provided by the AppComponent in its template.

app/movie.component.ts

import { Component, Input } from '@angular/core';
import { Actor } from './actor.model';

@Component({
  selector: 'app-movie',
  template: `
    <div>
      <h3>{{ title }}</h3>
      <p>
        <label>Actor:</label>
        <span>{{actor.firstName}} {{actor.lastName}}</span>
      </p>
    </div>`
})
export class MovieComponent {
  @Input() title: string;
  @Input() actor: Actor;
}

View Example

Last updated