I am trying to make a circle board in Angular2. For the example I want to make 10 circles but in reality this number can change. I want to calculate the radius of each circle, so it would be dynamic and not static. See the picture for example
This is my code
@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;
}
}
But I get the following error:
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]
Is there maybe a better way of writing this for loop with *ngFor
instead of writing this in a separate method?
In development mode (the default), change detection is run twice to ensure that model changes have stabilized. This means that the ngFor
loop is evaluated twice. Hence property x
will continue to be decremented the second time change detection runs. Other activity in your app will also cause change detection to run, and x
will continue to be decremented. Therefore, you must write all view functions, like calculateRadius()
, assuming they will be executed many times. E.g.:
public calculateRadius(i):number{
return this.x - i*this.distanceBetweenCircles;
}
The Template Syntax dev guide mentions this when it describes idempotent expressions.
This will also solve the value has changed after it was checked
problem.
You also need to bind SVG attribute r
using this syntax: [attr.r]="..."
, not [style.r]="..."
.
Plunker
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With