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

@Component({
  moduleId: module.id,
  selector: 'my-app',
  template: `
    <div class="jumbotron">
      <h1 class="display-7">ngOnChanges & ngDoCheck with ANGULAR.LOVE!</h1>
      <p class="lead">This is example of ngOnChanges & ngDoCheck lifecycles hooks</p>
    </div>
    <button (click)="mutateUserObject()">Mutate User object</button>
    <button (click)="changeReference()">Change reference</button>
    <ng-on-changes [user]="john"></ng-on-changes>
    <ng-do-check [user]="john"></ng-do-check>
  `
})
export class AppComponent {
  
  john : any = {
    firstName: 'Johnny',
    lastName: 'Cage',
    age: 36
  }
  
  mutateUserObject() : void {
    this.john.firstName = 'Michael'
  }
  
  changeReference() : void {
    this.john = {
      firstName: 'Bonny',
      lastName: 'Kevin',
      age: 12,
      city: 'New York'
    }
  }
}

import './rxjs-extensions';

import { NgModule }      from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule }   from '@angular/forms';
import { HttpModule }    from '@angular/http';

import { AppComponent }         from './app.component';
import { OnChangesComponent }   from './on-changes.component';
import { DoCheckComponent }     from './do-check.component';

@NgModule({
  imports: [
    BrowserModule,
    FormsModule,
    HttpModule
  ],
  declarations: [
    AppComponent,
    OnChangesComponent,
    DoCheckComponent
  ],
  bootstrap: [ AppComponent ]
})
export class AppModule { }
import { platformBrowser }    from '@angular/platform-browser';

import { AppModuleNgFactory } from '../aot/app/app.module.ngfactory';

platformBrowser().bootstrapModuleFactory(AppModuleNgFactory);
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { AppModule } from './app.module';

platformBrowserDynamic().bootstrapModule(AppModule);
// Observable class extensions
import 'rxjs/add/observable/of';
import 'rxjs/add/observable/throw';

// Observable operators
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/debounceTime';
import 'rxjs/add/operator/distinctUntilChanged';
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/filter';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/switchMap';
.row {
  margin-bottom: 20px;
  padding: 20px;
}

.card {
  margin-left: 20px;
  margin-right: 20px;
}

.child-child-child-cmp {
  border: 1px solid grey;
  border-radius: 3px;
  padding: 15px;
}
<!DOCTYPE html>
<html>
  <head>
    <base href="/">
    <title>Angular love - ngOnChanges & ngDoCheck</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.5/css/bootstrap.min.css" integrity="sha384-AysaV+vQoT3kOAXZkl02PThvDr8HYKPZhNT5h/CXfBThSRXQ6jW5DO2ekP5ViFdi" crossorigin="anonymous">
    <link rel="stylesheet" href="styles.css">

    <script src="shim.min.js"></script>
    <script src="zone.min.js"></script>
    <script>window.module = 'aot';</script>
  </head>

  <body>
    <my-app>Loading...</my-app>
  </body>
  <script src="dist/build.js"></script>
</html>
{
  "port": 8000,
  "files": ["./aot/**/*.{html,htm,css,js}"],
  "server": { "baseDir": "./aot" }
}
<!DOCTYPE html>
<html>
  <head>
    <script>document.write('<base href="' + document.location + '" />');</script>
    <title>Angular love - ngOnChanges & ngDoCheck</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.5/css/bootstrap.min.css" integrity="sha384-AysaV+vQoT3kOAXZkl02PThvDr8HYKPZhNT5h/CXfBThSRXQ6jW5DO2ekP5ViFdi" crossorigin="anonymous">
    <link rel="stylesheet" href="styles.css">

    <!-- Polyfills for older browsers -->
    <script src="https://unpkg.com/core-js/client/shim.min.js"></script>

    <script src="https://unpkg.com/zone.js@0.7.2?main=browser"></script>
    <script src="https://unpkg.com/reflect-metadata@0.1.8"></script>
    <script src="https://unpkg.com/systemjs@0.19.39/dist/system.src.js"></script>

    <script src="https://cdn.rawgit.com/angular/angular.io/b3c65a9/public/docs/_examples/_boilerplate/systemjs.config.web.js"></script>
    <script>
      System.import('app').catch(function(err){ console.error(err); });
    </script>
  </head>

  <body>
    <my-app>Loading...</my-app>
  </body>
</html>
{
  "compilerOptions": {
    "target": "es5",
    "module": "es2015",
    "moduleResolution": "node",
    "sourceMap": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "lib": ["es2015", "dom"],
    "noImplicitAny": true,
    "suppressImplicitAnyIndexErrors": true,
    "typeRoots": [
      "../../node_modules/@types/"
    ]
  },

  "files": [
    "app/app.module.ts",
    "app/main-aot.ts"
  ],

  "angularCompilerOptions": {
   "genDir": "aot",
   "skipMetadataEmit" : true
 }
}
import { Component, Input }          from '@angular/core';

@Component({
  moduleId: module.id,
  selector: 'ng-on-changes',
  template: `
    <p> {{ user.firstName }}, {{user.lastName}}, {{user.age}}</p>
  `
})
export class OnChangesComponent {
  @Input() user : any;
  
  constructor() {}
  
  ngOnChanges(changes: SimpleChanges) {
    console.log('ngOnChanges, previous User: ', changes.user.previousValue);
    console.log('ngOnChanges, next User: ', changes.user.currentValue);
    console.log('ngOnChanges, is first change?: ', changes.user.isFirstChange())
  }
}
import { Component, Input, DoCheck, KeyValueDiffers }          from '@angular/core';

@Component({
  moduleId: module.id,
  selector: 'ng-do-check',
  template: `
    <p> {{ user.firstName }}, {{user.lastName}}, {{user.age}}</p>
  `
})
export class DoCheckComponent implements DoCheck{
  @Input() user : any;
  differ : any;
  
  constructor(private differs: KeyValueDiffers) {
		this.differ = differs.find({}).create(null);
	}

  ngDoCheck() {
    if(this.user.firstName === 'Michael') {
      console.log('single property checked');
    }
    
    let changes = this.differ.diff(this.user);

		if (changes) {
			changes.forEachChangedItem(item => console.log('ngDoCheck, changed items ', item.currentValue));
			changes.forEachAddedItem(item => console.log('ngDoCheck, added items ' + item.currentValue));
			changes.forEachRemovedItem(item => console.log('ngDoCheck, removed items ' + item.currentValue));
		} else {
			console.log('no changes');
		}
  }
}