angularjs - Eroare de legare a metodei Angular2: „valoarea s-a schimbat după ce a fost verificată”


Încerc să fac o tablă circulară în Angular2. Pentru exemplu vreau să fac 10 cercuri, dar în realitate acest număr se poate schimba. Vreau să calculez raza fiecărui cerc, astfel încât să fie dinamică și nu statică. Vezi imaginea pentru exemplu

Acesta este codul meu

@Component({
    selector:"circle"
    template: `
  <svg>
    <circle *ngFor='#item of forLength #i=index #l=last #e=even'
            cx="50%" cy="50%" [style.r]="calculateRadius()" stroke="black" stroke-width="5" fill="white"></circle>
  <svg/>  
    `
})

export class CircleComponent{
    public maxRadius:number=25;
    public totalRounds:number=10;
    public x:number=30;

    public calculateRadius():number{
        var distanceBetweenCircles=this.maxRadius/(this.totalRounds-1);
        this.x-= distanceBetweenCircles;
        return this.x;
    }
}

Dar primesc următoarea eroare:

calculateRadius() in CircleComponent@7:30' has changed after it was checked. 
    Previous value: '-7.500000000000007'. 
    Current value: '-36.66666666666668' in [calculateRadius() in CircleComponent@7:30]

Există poate o modalitate mai bună de a scrie acest for loop cu *ngFor în loc să scrii acest lucru într-o metodă separată?

Răspuns #1

În modul de dezvoltare (implicit), detectarea schimbărilor este rulată de două ori pentru a se asigura că modificările modelului s-au stabilizat. Aceasta înseamnă că bucla ngFor este evaluată de două ori. Prin urmare, proprietatea x va continua să fie decrementată a doua oară când rulează detectarea schimbărilor. Alte activități din aplicația ta vor determina, de asemenea, rularea detectării schimbărilor, iar x va continua să fie decrementată. Prin urmare, trebuie să scrii toate funcțiile de vizualizare, cum ar fi calculateRadius(), presupunând că vor fi executate de multe ori. De exemplu:

public calculateRadius(i):number{
    return this.x - i*this.distanceBetweenCircles;
}

Ghidul pentru dezvoltatori al sintaxei șablonului menționează acest lucru atunci când descrie expresiile idempotente.

Acest lucru va rezolva, de asemenea, problema valoarea s-a schimbat după ce a fost verificată.

De asemenea, trebuie să legi atributul SVG r folosind această sintaxă: [attr.r]="...", nu [style.r]="...".

Plunker