2016-04-04 4 views
1

このエラーを議論しているいくつかのトピックを見て、自分のコードが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にこのエラーを再現したかったのですが、残念なことに例外はありません。私のアプリとプランナーの間の唯一の違いはattributeです。私のアプリでは、モデルであり、JSONオブジェクトではなく、何か変更することができますか?

+0

Plunkerの例は、したがって、それは再現性のあるべきbeta.8' 'で実行されます。 AFAIRは、削除後または削除中にイベントを発生させるコンポーネントに関連しています。 –

+0

確かに、インデックスにベータ8をロードしても、ベータ0と書かれているREADME.mdファイルを調べました。 それは私がgithub問題から理解したものですが、なぜ私の場合に起こるのか理解できません。 – Sunder

+0

readmeは時代遅れです。 –

答えて

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}); 
    } 
+0

' this.strings = [] '行のsetTimeOutが1ms(0は動作しませんでした)ありがとうございました。このコードを1ms遅らせると、削除されたコンポーネントからイベントが発生するのを防ぐことはできますか? – Sunder

+1

Angularが以前の変更を処理している間に、ナッジが変化することがあります。 'setTimeout'は物事が処理される順序を変えるだけです。 Angularはそれを完了することができ、このコードはAngularが再び安定した状態になったときにのみ実行されます。問題が角度で固定されている場合、予想された順序から実行されないことが内部的に考慮される必要があります。 –