In a simplified way I have an Angular2 Component and an input object like this:
class MyObject{
Prop1:string;
Prop2:Number;
}
@Component()
export class
In fact, by default Angular2 detects changes when object reference is updated not its content. But this default behavior can be changed by using the DoCheck
interface.
In your case (detecting that a property was updated into the myObject
object, you could use the following approach:
@Component({
selector: 'my-component',
(...)
})
export class MyComponent implements DoCheck {
@Input() myObject: MyObject;
differ: any;
constructor(differs: KeyValueDiffers) {
this.differ = differs.find([]).create(null);
}
ngDoCheck() {
var changes = this.differ.diff(this.myObject);
if (changes) {
changes.forEachChangedItem((elt) => {
if (elt.key === 'prop1') {
this.doSomethingIfProp1Change();
}
});
}
}
doSomethingIfProp1Change() {
console.log('doSomethingIfProp1Change');
}
}
When the value of the prop1
property is updated, the doSomethingIfProp1Change
method is called.
See this plunkr: http://plnkr.co/edit/uvOKMXQa9Ik8EiIhb60Y?p=preview.
You can use observables to support notification of subscribers. Angular itself doesn't provide support for observing changes of internal object state.
class MyObject{
constructor() {
this.prop1Change$ = new Observable(observer =>
this._prop1Observer = observer).share(); // share() allows multiple subscribers
this.prop2Change$ = new Observable(observer =>
this._prop2Observer = observer).share();
console.debug(this._prop2Observer);
}
prop1Change$: Observable<string>;
private _prop1Observer: Observer;
_prop1:string;
get prop1():string { return this._prop1 };
set prop1(value:string) {
this._prop1 = value;
this._prop1Observer && this._prop1Observer.next(value);
}
prop1Change$: Observable<number>;
private _prop2Observer: Observer;
_prop2:Number;
get prop2():number { return this._prop2 };
set prop2(value:number) {
this._prop2 = value;
console.debug(this);
this._prop2Observer && this._prop2Observer.next(value);
}
}
This code could be shortened by using Subject
but Observable
should be favored over Subject
.
@Component()
export class MyComponent{
@Input() myObject: MyObject;
count2:number;
DoSomethingIfProp1Change(){
console.log(myObject.prop1);
}
ngOnChanges(changes: {[propName: string]: SimpleChange}) {
console.log('changes');
if(changes['myObject']) {
if(this.prop2Subscription) {
this.prop2Subscription.unsubscribe();
}
this.prop2Subscription = this.myObject.prop2Change$.subscribe(value => {
this.count2 = value;
console.log('count2: ' + value);
});
// same for `prop2`
}
}
}
Plunker example
See also Delegation: EventEmitter or Observable in Angular2