角度异常:尝试使用脱水检测器

时间:2016-04-04 14:00:01

标签: angular

在查看讨论此错误的几个主题后,我找不到任何理由让我的代码生成EXCEPTION: Attempt to use a dehydrated detector: PortsInputComponent_1 -> valueChange。我不认为stacktrace是有用的,因为它只是角度代码,而不是我的。

我查看了这些帖子:Angular2 EXCEPTION: Attempt to detect changes on a dehydrated detectorEXCEPTION: Attempt to detect changes on a dehydrated detectorWhat is a dehydrated detector and how am I using one here?以及此github问题https://github.com/angular/angular/issues/6786

他们似乎都在使用一些异步操作,我不是,并且这些解决方案都不适合我的项目。请不要将其作为副本关闭。

基本上我要做的是为多个端口提供特殊输入。我希望始终有一个空白输入,因此用户无需按下按钮即可添加新按钮。我不希望有多个空白输入,所以我需要在用户删除最后一个字符时删除它们。下面的演示非常完美。

以下是plunker中的代码:

import { Component, Input }             from 'angular2/core';

@Component({
  selector: 'my-ports-input',
  template:`
<div layout-gt-sm="row" layout-wrap>

  <md-input-container class="md-block" flex-gt-sm
      *ngFor="#port of values() ; #i = index ;">
    <label>Port</label>
    <input md-input class="ports-input" type="text" size="6"
        [value]="port.title" (input)="changeValueAtIndex(i, $event)" />
  </md-input-container>
</div>
`
})

export class PortsInputComponent {
  // More complex model that contains an array of string values
  @Input() attribute: {value : string[]}
  strings = []

  changeValueAtIndex(index, event) {
    // Case where we changed the value of the latest port : we add a new input
    if (!this.attribute.value[index]) {
      this.strings.push({ title: '' })
    }

    this.attribute.value[index] = event.target.value

    if (event.target.value.length === 0) {
      this.attribute.value.splice(index, 1)
      this.strings = [] // Should reload the array, but also causes the issue below
    }
  }

  // Use this function that returns an array of objects instead of an array of string.
  // Using directly attribute.value (array of string) cause this error:
  // https://github.com/angular/angular/issues/6786
  //
  // Returning directly this.attribute.value.map((value) => { return {title: value} })
  // causes an infinite loop of error... for some reason
  // So use an intermediate variable instead
  values() {
    if (!this.strings.length) {
      let values: string[] = this.attribute.value
      this.strings = values.map((value) => { return {title: value} })
      this.strings.push({ title: '' })
    }
    return this.strings
    // return this.attribute.value.map((value) => { return {title: value} })
  }
}

有没有人理解为什么会出现这种错误?

我想在a plunker中重现此错误,但不幸的是它不会导致任何异常,我在应用和plunker之间看到的唯一区别是attribute变量。在我的应用程序中,它是一个模型,而不是一个JSON对象,它可以改变一些东西吗?

1 个答案:

答案 0 :(得分:1)

延迟这段代码可能会解决(未经测试,因为我无法重现)

  changeValueAtIndex(index, event) {
    setTimeout(() => {
      // Case where we changed the value of the latest port : we add a new input
      if (!this.attribute.value[index]) {
        this.strings.push({ title: '' })
      }

      this.attribute.value[index] = event.target.value

      if (event.target.value.length === 0) {
        this.attribute.value.splice(index, 1)
        this.strings = [] // Should reload the array, but also causes the issue below
      }
    },0});
  }