2017-07-25 52 views
2

我是Angular 4的新手。我有一个如下所示的数据绑定字段。但不知何故,有一个ExpressionChangedAfterItHasBeenCheckedError。数据绑定导致ExpressionChangedAfterItHasBeenCheckedError

<form> 
<div> 
    <h2>Hello {{input.value}}</h2> 
    <input type="text" [value]="input.value" name="inputTest"/> 
    <input type="text" #input [value]="name"/> 
</div> 
<button type="submit">submit</button> 
</form> 

下面是一个简单的构造:

export class App { 
    name:string; 
    constructor() { 
    this.name = `Angular! v${VERSION.full}` 
    } 
} 

我读了很多有关错误的帖子,我还是不明白,为什么一个简单的数据绑定将导致错误。

我尝试了下面的代码,但不起作用。

ngAfterViewInit() { 
    console.log("ngAfterViewInit"); 
    this.cd.detectChanges(); 
} 

请帮忙!!

请参考plunker:https://plnkr.co/edit/16atvKgf2BA6z2OjqT6h?p=preview

+0

这个帖子[所有你需要知道的关于'ExpressionChangedAfterItHasBeenCheckedError'错误](https://hackernoon.com/everything-you-need-to-know-about-the-expressionchangedafterithasbeencheckederror-错误 - e3fd9ce7dbb4)应该给你的见解。如果没有,创建一个重现问题并将其张贴在这里的重击器 –

+0

@Maximus我添加了重击器。我认为代码非常简单,但会引发错误。 –

+0

没有错误引发你引用 –

回答

2

作为操作的Everything you need to know about change detection in Angular一个解释,角执行是DOM更新。这包括插值和绑定更新。 Angular按照它们在模板中找到的顺序为每个DOM执行这些操作。这些操作在The mechanics of DOM updates in Angular中解释。

您的模板看起来是这样的:

<h2>Hello {{input.value}}</h2> 
    <input type="text" #input [value]="name"/> 

所以角开始更新DOM和第一执行对h2元素的更新。它将{{input.value}}评估为空字符串,因为它尚未更新input上的value绑定。因此它将h2更新为Hello并记住空字符串值。然后继续更新input-[value]="name"的绑定,并将其值设置为Angular! v4.3.1。变更检测在此阶段完成。

然后它运行验证阶段,如Everything you need to know about the ExpressionChangedAfterItHasBeenCheckedError error中所述。在验证阶段,Angular评估{{input.value}}并将其与之前的值进行比较。由于输入已经被处理,所以表达式求值为Angular! v4.3.1,其与在变化检测期间用于h2元素的空字符串不同。所以,你得到一个错误:

Expression has changed after it was checked. Previous value: ''. Current value: 'Angular! v4.3.1'.

这也意味着,如果您更改模板中的元素的顺序,你会看到没有错误。该工程确定:

<input type="text" #input [value]="name"/> 
<h2>Hello {{input.value}}</h2> 
+1

好吧一如既往地说! – yurzui

+0

@yurzui,感谢upvote) –