Angular2方法绑定错误:"值在检查后发生了变化"

时间:2016-02-29 22:22:13

标签: angularjs data-binding typescript angular

我正在尝试在Angular2中创建一个圆形板。例如,我想制作10个圆圈,但实际上这个数字可以改变。我想计算每个圆的半径,所以它是动态的而不是静态的。请参见图片enter image description here

这是我的代码

@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;
    }
}

但是我收到以下错误:

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]

是否有更好的方法可以使用*ngFor为循环编写此代码而不是在单独的方法中编写此代码?

2 个答案:

答案 0 :(得分:15)

在开发模式(默认设置)下,更改检测为run twice,以确保模型更改已稳定。这意味着ngFor循环被评估两次。因此,在第二次更改检测运行时,属性x将继续递减。您应用中的其他活动也会导致更改检测运行,x将继续递减。因此,您必须编写所有视图函数,例如calculateRadius(),假设它们将被执行多次。 E.g:

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

模板语法开发指南在描述idempotent expressions时会提到这一点。

这也将解决value has changed after it was checked问题。

您还需要使用以下语法绑定SVG属性r[attr.r]="...",而不是[style.r]="..."

Plunker

答案 1 :(得分:0)

  

“检查后价值发生了变化”

任何value的回报必须是确定性的。表示如果我使用相同的输入调用value(可能是calculateRadius()),则应该提供相同的输出。

所以将index传递给calculateRadius(或value提供该错误的任何内容)