(click) broken inside *ngFor on elements of type array if coming from a function

in plnkr I’ve reproduced a strange edge case. It probably depends on pixijs or perhaps on webgl as it happens when using pixijs.

Notice how you can click on all the elements of the lists but as soon as you start using pixijs (just click on the button) the click stop working on the element of type array. The odd thing is that it still works on all the other elements. It is even odder that if instead of using a function to return an array, it is used an inline array, all works as expected…

any ideas ?

app.component.ts

<button *ngIf="!renderer" (click)="breakIt()">break me</button> 
<span *ngIf="renderer">BROKEN</span>
Clicked: {{clicked | json}}

<h2>It breaks</h2>
<h3 *ngFor="#n of ns()" (click)="click(n)">{{n | json}}</h3>

<h2>It works</h2>
<h3 *ngFor="#n of [[2,4],'ciao',4,true]" (click)="click(n)">{{n | json}}</h3>

app.component.html

import {Component} from 'angular2/core';

@Component({
    selector: 'my-app',
    templateUrl: './app/app.component.html'
})
export class AppComponent { 
  clicked = "";
  renderer;

  breakIt() {
    this.renderer = PIXI.autoDetectRenderer(200, 200,{backgroundColor : 0x1099bb});
  }

  ns() {
    return [[2,4],'ciao',4,true];
  }

  click(n) {
    this.clicked=n;  
  }
}

2
Leave a Reply

avatar
2 Comment threads
0 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
1 Comment authors
Jason Recent comment authors
  Subscribe  
newest oldest most voted
Notify of
Jason
Guest

The problem is caused by ns() { return [[2,4],'ciao',4,true]; } and <h3 *ngFor="#n of ns()" With every event Angular invokes change detection and each time it checks whether the previously returned value from ns() is the same as the current one it turns out to be different every time, because each call to ns() returns a new array. Angular expects the model to stabilize. Angular doesn’t compare properties or the contents of objects and arrays, it only does identity checks and ns() for every call returns a new and thus different array instance. Instead it should be var arr =… Read more »

Jason
Guest

Interesting, you are getting infinite change loop. I happens because each time you return new array from ns() AND PIXI.autoDetectRenderer somehow triggers angular change event.

Tried to set changeDetection:ChangeDetectionStrategy.OnPush – it works. So i guess angular detects periodic changes in renderer object and starts processing changes and can not stop since every time template value != ns() method result.