NativeScript + Angular 2 - ListView template child component @Input

I ran into an issue (actually, more of a gotcha) where the @Input of a ListView template's child was becoming 'out of sync' with the parent template, causing all sorts of bizarre behavior.

I made a little demo app that illustrates this:

The problem was that my initial version of the child component was using OnInit to set an instance variable:

subComponent.component.ts (broken version)

import {Component, ChangeDetectionStrategy, OnInit, Input} from "@angular/core";

@Component({
    selector: "sub-component",
    templateUrl: "subComponent.component.html",
    changeDetection: ChangeDetectionStrategy.OnPush
})
export class SubComponentComponent implements OnInit {  
    @Input() myItem: number;
    count: number = 0;

    ngOnInit(): void {
        this.count = this.myItem;
    }
}

I knew that OnInit would only get called once when the component was created, but this wasn't something that was going to change for a given parent component, so I didn't see why that would be a problem.

It seems that these components get reused by ListView (which makes sense for performance reasons), so while the parent gets freshly bound variables, it doesn't get updated in the child because the component instance was already initialized, and OnInit won't be run again.

Once that is realized, the solution is pretty obvious, use OnChanges!!

subComponent.component.ts (fixed version)

import {Component, ChangeDetectionStrategy, Input, OnChanges, SimpleChanges} from "@angular/core";

@Component({
    selector: "sub-component",
    templateUrl: "subComponent.component.html",
    changeDetection: ChangeDetectionStrategy.OnPush
})
export class SubComponentComponent implements OnChanges {  
    @Input() myItem: number;
    count: number = 0;

    ngOnChanges(changes: SimpleChanges) {
        this.count = changes['myItem'].currentValue;
    }
}

Credit and thanks to Nick Iliev for confirming this issue, improving the official example code, and suggesting a good post on it.