Change-detection not working properly in ng2 component after navigation via angular1 ui-router
<p>In an application that uses ng-upgrade to use some new ng2 (V2.2.4) components inside a big ng1 (V1.5.9) app (using ui-router) I am currently seeing a very strange change-detection issue. As far as I can tell, this has been introduced in some upgrade of ng2, but sadly I can't easily verify that currently.</p>

<p>I have reduced it to a minimal example by now where i simply have this component:</p>

<pre><code>@Component({
    selector:'my-ng2-demo',
    template: '&lt;div&gt;{{status}}&lt;/div&gt;'
})
export class MyNg2Demo implements OnDestroy {
    public status:boolean = true;
    private interval:any;

    constructor() {
        this.interval = setInterval(() =&gt; {
            this.status = !this.status;
            console.log('status: ' + this.status);
        }, 2000);
    }

    ngOnDestroy():void {
        clearInterval(this.interval);
    }

}
</code></pre>

<p>That component is upgraded in the upgrade-adapter and registered as an entry-component in the module.</p>

<p>The component is used in the template of an ng1 controller like this:</p>

<pre><code>&lt;my-ng2-demo&gt;&lt;/my-ng2-demo&gt;
</code></pre>

<p>When I open a browser and navigate directly to that page (the route of the ng1 controller) everything works as expected: the ui shows true/false alternating every 2 seconds.</p>

<p>However: when I navigate away &amp; then come back to the page (visiting some different routes) then suddenly change detection doesn't seem to work. The displayed value alternates only about every 5-6 seconds, seems quite random, although in the console I still see the expected values.</p>

<p>When I change the component's constructor to this:</p>

<pre><code>constructor(private zone: NgZone) {
    this.interval = setInterval(() =&gt; {
        zone.run(() =&gt; {
            this.status = !this.status;
            console.log('status: ' + this.status);
        });
    }, 2000);
}
</code></pre>

<p>It suddenly works again.</p>

<p>Obviously this isn't a feasible solution since the behavior I'm seeing in the real app is much more complex (i would have to add <code>zone.run</code> in dozens of places probably, which would not be maintainable).</p>

<p>I have debugged this for hours and don't understand what is happening.
In Chrome's JavaScript profiler, I basically see that the page idles for almost the whole time in those 5-6 seconds where nothing happens.</p>

<p><a href="https://i.stack.imgur.com/ULhJ2.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/ULhJ2.png" alt="profiler"></a>
This is not a screenshot from that demo-component (but it basically looks the same) but from profiling the tab-component I was initially testing (tab-switching took just as long with no visible actions in between).</p>

<p><strong>update:</strong></p>

<p>After a bit more experimentation what I find quite surprising also is that when instead of putting the status-changing code into a <code>zone.run</code> call, I add a call to <code>ApplicationRef.tick()</code>
 (as mentioned here for example: <a href="https://stackoverflow.com/a/34829089/1335619">https://stackoverflow.com/a/34829089/1335619</a> ) it also does NOT work at all.
I don't understand why forcing a complete application-change-detection does nothing, but a zone-run call somehow works.</p>

<p>Example code with tick call which does not work:</p>

<pre><code>constructor(private applicationRef:ApplicationRef) {
    this.interval = setInterval(() =&gt; {
        this.status = !this.status;
        console.log('status: ' + this.status);
        applicationRef.tick();
    }, 2000);
}
</code></pre>