2 个组件之间的 2 种方式绑定仅适用于第一个字母
2 way binding between 2 components works only on first letter
我遇到了一个非常严重的 运行ge 错误,我已经研究过了,但我很难弄清楚。我发现的大多数相似项目在最终更改前大约已有一年的历史,现在无法使用。
错误信息
Expression has changed after it was checked. Previous value: 'Angular2'. Current value: 'Angular2x'.
出于某种原因,当它以 2 种方式绑定到 属性 时抛出异常。
我认为错误发生在以下代码运行之后。
ngDoCheck(){
this.bindingPropertyChange.emit(this.bindingProperty)
}
我创建了一个 Plunker 来重现错误。
Plunker here
有人知道为什么会这样吗?如果是这样,您能解释一下为什么抛出这个异常吗?
我不是说 ngDoCheck
的合适人选,但 ngDoCheck
[ 似乎有问题=28=]。其他人可以提出建议,并且可以编辑我的答案以说明有关 ngDoCheck
.
的任何内容
但截至目前,您可以使用 keyup
事件并将函数与其绑定,如下所示,
演示 : https://plnkr.co/edit/hSrPuWNyJd6Az8sHXh1T?p=preview
<input [(ngModel)]="bindingProperty" (keyup)="check()" class="form-control"/>
check(){
this.bindingPropertyChange.emit(this.bindingProperty)
}
ngDoCheck 是你的问题,原因如下:
ngDoCheck 会在您的模型内部发生变化后触发。
在您输入字母后,angular 开始检查所有地方(整个应用程序)是否有任何相关更改,Angular 运行仅在更改后进行一次更改检测,之后应该不会有任何更新。(单向数据流,仅一次检查)。
假设更改检测 运行 ( ngDoCheck ) 成功并相应地更新了 UI,但是在检查过程中,您突然进行了另一个更改。
在 开发模式 中,Angular2 运行 在第一个之后进行另一个更改检测,以确保在第一个之后没有任何更改,并且因为你发射了那个事件并再次默默地改变了模型,angular 生气并抛出错误。
但是,在 Prod 模式 中,Angular 不会 运行 第二次检查,因此您不会在生产中看到此错误,但是您的模型更新 ( emit ) 不会反映在 UI 中。(要对此进行测试,只需将 ngCore.enableProdMode();
添加到您的 main.ts
文件中,错误就会消失)。
这里有几种方法可以解决这个问题:
1- 改变你的策略,就像在我的 First Plunker 中,你可以简单地使用对象绑定并绕过这个问题。
2- 使用 setTimeout 推迟您的更改,这将 运行 另一个更改检测并使 angular 高兴:
ngDoCheck(){
setTimeout(()=>{
this.bindingPropertyChange.emit(this.bindingProperty)
});
}
这里是 plunker
3- 不要使用 ngDoCheck 并使用 (input) 或 (keyup) 或类似事件在另一个循环中发出您的更改,这再次使 Angular 到 运行 另一个更改检测:
注意 我建议使用 (input) 而不是 keyup 或 keydown 或类似的,原因是如果你使用 keyup/keydown ,更新将不会是无缝的,因为如果你按下一个键并按住它,直到你释放键,更新才会发生,但是使用 (input) ,它会立即发生,就像你在评论中说的那样,如果用户要用鼠标复制粘贴他们是不使用键,它不会更新模型。
<input [(ngModel)]="bindingProperty" (input)="emitUp()" class="form-control"/>
emitUp(){
this.bindingPropertyChange.emit(this.bindingProperty)
}
这是Plunker
我遇到了一个非常严重的 运行ge 错误,我已经研究过了,但我很难弄清楚。我发现的大多数相似项目在最终更改前大约已有一年的历史,现在无法使用。
错误信息
Expression has changed after it was checked. Previous value: 'Angular2'. Current value: 'Angular2x'.
出于某种原因,当它以 2 种方式绑定到 属性 时抛出异常。
我认为错误发生在以下代码运行之后。
ngDoCheck(){
this.bindingPropertyChange.emit(this.bindingProperty)
}
我创建了一个 Plunker 来重现错误。 Plunker here
有人知道为什么会这样吗?如果是这样,您能解释一下为什么抛出这个异常吗?
我不是说 ngDoCheck
的合适人选,但 ngDoCheck
[ 似乎有问题=28=]。其他人可以提出建议,并且可以编辑我的答案以说明有关 ngDoCheck
.
但截至目前,您可以使用 keyup
事件并将函数与其绑定,如下所示,
演示 : https://plnkr.co/edit/hSrPuWNyJd6Az8sHXh1T?p=preview
<input [(ngModel)]="bindingProperty" (keyup)="check()" class="form-control"/>
check(){
this.bindingPropertyChange.emit(this.bindingProperty)
}
ngDoCheck 是你的问题,原因如下:
ngDoCheck 会在您的模型内部发生变化后触发。
在您输入字母后,angular 开始检查所有地方(整个应用程序)是否有任何相关更改,Angular 运行仅在更改后进行一次更改检测,之后应该不会有任何更新。(单向数据流,仅一次检查)。
假设更改检测 运行 ( ngDoCheck ) 成功并相应地更新了 UI,但是在检查过程中,您突然进行了另一个更改。
在 开发模式 中,Angular2 运行 在第一个之后进行另一个更改检测,以确保在第一个之后没有任何更改,并且因为你发射了那个事件并再次默默地改变了模型,angular 生气并抛出错误。
但是,在 Prod 模式 中,Angular 不会 运行 第二次检查,因此您不会在生产中看到此错误,但是您的模型更新 ( emit ) 不会反映在 UI 中。(要对此进行测试,只需将 ngCore.enableProdMode();
添加到您的 main.ts
文件中,错误就会消失)。
这里有几种方法可以解决这个问题:
1- 改变你的策略,就像在我的 First Plunker 中,你可以简单地使用对象绑定并绕过这个问题。
2- 使用 setTimeout 推迟您的更改,这将 运行 另一个更改检测并使 angular 高兴:
ngDoCheck(){
setTimeout(()=>{
this.bindingPropertyChange.emit(this.bindingProperty)
});
}
这里是 plunker
3- 不要使用 ngDoCheck 并使用 (input) 或 (keyup) 或类似事件在另一个循环中发出您的更改,这再次使 Angular 到 运行 另一个更改检测:
注意 我建议使用 (input) 而不是 keyup 或 keydown 或类似的,原因是如果你使用 keyup/keydown ,更新将不会是无缝的,因为如果你按下一个键并按住它,直到你释放键,更新才会发生,但是使用 (input) ,它会立即发生,就像你在评论中说的那样,如果用户要用鼠标复制粘贴他们是不使用键,它不会更新模型。
<input [(ngModel)]="bindingProperty" (input)="emitUp()" class="form-control"/>
emitUp(){
this.bindingPropertyChange.emit(this.bindingProperty)
}
这是Plunker