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');
}
}
}