My child component as following:
'use strict';
import {Component, Input, OnInit, OnChanges, ChangeDetectionStrategy, ElementRef} from 'angular2/core';
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
selector: 'my-app',
template: ''
})
export class MyApp implements OnInit {
@Input() options: any;
constructor(private el: ElementRef) {
}
ngOnInit() {
}
ngOnChanges(...args: any[]) {
console.log('changing', args);
}
}
And Parent component as following:
'use strict';
import {Component, Input} from 'angular2/core';
import {MyApp} from './MyApp';
@Component({
selector: 'map-presentation',
template: `<my-app [options]="opts"></my-app>
<button (click)="updates($event)">UPDATES</button>
`,
directives: [MyApp]
})
export class MainApp {
opts: any;
constructor() {
this.opts = {
width: 500,
height: 600
};
}
updates() {
console.log('before changes');
this.opts = {
name: 'nanfeng'
};
}
}
Each time while i clicked the "UPDATES" button, the ngOnChanges
method never be called, but why?
I angular version i am using is "2.0.0-beta.8"
Current behaviorWhen dynamically creating components, manually changing a property of a child component of that created component and then triggering changeDetection, ngOnChanges on this child component does not get called.
When should you use ngOnChanges? Use ngOnChanges whenever you want to detect changes from a variable decorated by @Input. Remember that only changes from the parent component will trigger this function. Also remember that changes from the parent still update the child value even without implementing ngOnChanges.
The ngOnChnages is a life cycle hook, which angular fires when it detects changes to data-bound input property. This method receives a SimpeChanges object, which contains the current and previous property values. The child Component decorates the property using the @Input decorator.
ngOnInit DOES NOT FIRE.
It's working
app.ts
import {Component} from 'angular2/core';
import {child} from 'src/child';
@Component({
selector: 'my-app',
providers: [],
template: `
<child-cmp [options]="opts"></child-cmp>
<button (click)="updates($event)">UPDATES</button>
`,
directives: [child]
})
export class App {
opts: any;
constructor() {
this.opts = {
width: 500,
height: 600
};
}
updates() {
console.log('after changes');
this.opts = {
name: 'micronyks'
};
}
};
child.ts
import {Input,Component,Output,EventEmitter} from 'angular2/core';
import {Component, Input, OnInit, OnChanges, ChangeDetectionStrategy, ElementRef} from 'angular2/core';
@Component({
selector: 'child-cmp',
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
`
})
export class child {
@Input() options: any;
ngOnChanges(...args: any[]) {
console.log('onChange fired');
console.log('changing', args);
}
}
Well it works with "input properties", this means with those passed in this format: @Input() myVariable: string;
I made it work normally when this input value is a string, number or boolean, but with objects I still do not now what's going on.
So, in the "AppComponent" template (the .html) can go something like this:
<input type="text" [(ngModel)]="name"> // name is a string property of the AppComponent
<app-test [myVal]="name"></app-test>
And the "test component" can look like this:
import {Component, Input } from '@angular/core';
@Component({
selector: 'app-test',
template: `
<div> TEST COMPONENT {{myVal}}</div>
`,
styles: []
})
export class TestComponent {
constructor() { }
ngOnChanges(changeRecord: SimpleChanges) {
console.log('It works!');
/* changeRecord will have a property for each INPUT named the same
as the input. These are added to changeRecord when the input
gets a value */
if(typeof changeRecord.myVal !== 'undefined){
console.log('myVal = ', changeRecord.myVal.currentValue);
}
}
@Input() myVal: string;
}
Cheers.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With