Angular2 subscribing to changes to @Input in Child Component
I have a parent and child component. Parent component has index
and passes this through to the child component as an @Input
. This index
value constantly changes in the parent component, and inside my child component, I want to run a function everytime the Parent component changes index
. This has a slide component that constantly changes it. How can I achieve this? I've tried with the below code (this.index.subscribe(() =>
), but I'm getting that it's not a function everytime I try and initialise the subscription.
EDIT: There is no related code in the Child
template that could impact this, so it's not provided. ngOnChange
doesn't seem to work as the change is happening in the directive as opposed to the parent
's template.
Child:
import {Component, OnInit, ViewChild, Input} from '@angular/core';
import {Observable} from 'rxjs/Observable';
@Component({
selector: "child",
templateUrl: "components/child/child.html",
})
export class ChildComponent implements OnInit {
@Input() index: string;
currentIndex: any;
constructor() {}
ngOnInit() {}
ngOnChanges(){}
ngAfterViewInit() {
console.log("index " + this.index);
this.currentIndex = this.index.subscribe(() => {
console.log("index " + this.index);
})
}
ngOnDestroy() {
this.currentIndex.unsubscribe();
}
}
Parent:
import {Component, ElementRef, OnInit, ViewChild} from '@angular/core';
import {Page} from "ui/page";
import {ChildComponent} from '/components/child/child.component'
@Component({
selector: "parent",
template: "<child [index]="index"></child>",
directives: [ChildComponent]
})
export class ParentComponent implements OnInit {
index: string = "0,1";
constructor(private page: Page) {
}
}
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.
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