2个组件之间的双向绑定仅适用于第一个字母

时间:2016-12-31 15:40:23

标签: angular events 2-way-object-databinding

我得到一个非常奇怪的错误,我已经研究过,我很难搞清楚。我发现的大多数项目都是在最终更改之前大约一年,现在不起作用。

错误消息

  

检查后表情发生了变化。之前的价值:' Angular2'。当前价值:' Angular2x'。

出于某种原因,当它以2路方式绑定到该属性时,它会抛出一个异常。

我认为在运行以下代码后会发生错误。

  ngDoCheck(){
    this.bindingPropertyChange.emit(this.bindingProperty)
  }

我创建了一个Plunker来重现错误。 Plunker here

有谁知道为什么会这样?如果是这样,你能解释为什么抛出这个异常吗?

2 个答案:

答案 0 :(得分:2)

ngDoCheck是你的问题,原因如下:

ngDoCheck会在模型内部发生变化后触发。

在您输入的字母后,angular开始检查任何地方(整个应用程序)是否有任何相关更改,Angular在更改后只运行一次更改检测,之后不应该有任何更新。(单向数据流,只检查一次。)

让我们说成功运行变更检测(ngDoCheck)并相应地更新UI,但在检查过程中,您突然进行了另一次更改。

开发模式中,Angular2在第一个之后运行另一个changeDetection以确保在第一个之后没有任何变化,并且因为你发出了该事件并且再次无声地更改了模型,角度很生气抛出错误。

但是,在产品模式中,Angular不会运行第二次检查,因此您不会在生产中看到此错误,但您的模型更新(发布)不会反映在UI中。 (要对此进行测试,只需将ngCore.enableProdMode();添加到main.ts文件中,错误就会消失。

以下是解决这个问题的几种方法:

1-更改您的策略,例如在我的First Plunker中,您只需使用对象绑定并绕过问题。

2-使用setTimeout推迟你的更改,这将运行另一个更改检测并使角度快乐:

ngDoCheck(){
    setTimeout(()=>{
      this.bindingPropertyChange.emit(this.bindingProperty)
    });

  }

以下是plunker

3-不要使用ngDoCheck并使用(输入)或(keyup)或类似事件在另一个周期中发出更改,这再次使Angular运行另一个更改检测:

注意我建议使用(输入)over keyup或keydown或类似的,原因是如果你使用keyup / keydown,更新将不会无缝,因为如果你按一个键并保持在那里更新将不会发生,直到您释放密钥,但有(输入),它会立即发生,就像你在评论中说,如果用户要用鼠标复制粘贴他们没有使用密钥和它不会更新模型。

<input [(ngModel)]="bindingProperty" (input)="emitUp()" class="form-control"/>

emitUp(){
    this.bindingPropertyChange.emit(this.bindingProperty)
  }

以下是Plunker

答案 1 :(得分:1)

我不是对 ngDoCheck 说些什么的合适人选,但似乎 ngDoCheck 存在问题。其他人可以建议并且可以编辑我的答案,以便对 ngDoCheck 说些什么。

但截至目前,您可以使用 keyup 事件并使用它绑定一个函数,如下所示,

DEMO https://plnkr.co/edit/hSrPuWNyJd6Az8sHXh1T?p=preview

<input [(ngModel)]="bindingProperty" (keyup)="check()" class="form-control"/>

check(){
    this.bindingPropertyChange.emit(this.bindingProperty)
}