Angular2 subscribing to changes to @Input in Child Component
As mentioned in the other answer, you can use ngOnChanges
life hook. From Angular`s documentation:
ngOnChanges: Respond after Angular sets a data-bound input property. The method receives a changes object of current and previous values.
Check the example below to see how you can use it:
import { Component, Input, OnChanges } from '@angular/core';
@Component({
selector: 'child',
template: `
Value:
<span>{{ value }}</span>
<br />
<br />
Number of changes: {{ numberOfChanges }}
`
})
export class ChildComponent implements OnChanges {
@Input() value: any;
private numberOfChanges: number = 0;
ngOnChanges() {
this.numberOfChanges++;
}
}
Plunker: http://plnkr.co/edit/XjD1jjCnqiFdbhpTibIe
Another solution for "transforming" the changing value into an observable should be
@Input() status: Status;
private status$: Subject<Status>;
constructor() {
this.status$ = new Subject<Status>();
}
ngOnChanges(changes: {[propertyName: string]: SimpleChange}) {
this.status.next(this.status);
}
ngOnChange
is called each time an input parameter changes. You even have it in your Child
component, but it's not implemented correctly:
ngOnChanges(changes: {[propertyName: string]: SimpleChange}) {
// check the object "changes" for new data
}
More details: https://angular.io/docs/ts/latest/guide/lifecycle-hooks.html#!#onchanges
Update: index
in the parent component is a string
. For some reason it became an Observable
in the child component.
https://angular.io/docs/ts/latest/api/core/index/Input-var.html
To quote:
Angular automatically updates data-bound properties during change detection.
If you need to do some processing on the input, look at the get and set. https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#parent-to-child-setter
From the documentation, here is an example.
import { Component, Input } from '@angular/core';
@Component({
selector: 'name-child',
template: `
<h3>"{{name}}"</h3>
`
})
export class NameChildComponent {
_name: string = '<no name set>';
@Input()
set name(name: string) {
this._name = (name && name.trim()) || '<no name set>';
}
get name() { return this._name; }
}
You don't need to use an observable.