2016-04-04 13 views
1

Bu hatayı tartışan çeşitli konulara baktıktan sonra, kodumun EXCEPTION: Attempt to use a dehydrated detector: PortsInputComponent_1 -> valueChange ürününü üretmesi için bir neden bulamıyorum. Stacktrace'in yararlı olduğunu sanmıyorum, çünkü sadece açısal kod ve benim değil.Köşeli özel durum: susuz detektör kullanma girişiminde bulunma

O mesajların baktım

: Angular2 EXCEPTION: Attempt to detect changes on a dehydrated detector, EXCEPTION: Attempt to detect changes on a dehydrated detector, What is a dehydrated detector and how am I using one here? ve bu github konuya https://github.com/angular/angular/issues/6786 de.

Hepsinin, eşzamansız bazı işlemleri kullanıyormuş gibi görünmediklerini ve bu çözümlerin hiçbirinin projeme uymadığını görüyoruz. Lütfen kopya olarak kapatmayın.

Temel olarak, yapmaya çalıştığım şey birden çok bağlantı noktası için özel bir girdidir. Her zaman boş bir giriş yapmak istiyorum, bu yüzden kullanıcının yeni bir tane eklemek için bir düğmeye basması gerekmez. Yine de birden fazla boş girdim olmasını istemiyorum, bu yüzden kullanıcı son karakteri sildiğinde bunları kaldırmam gerekiyor. Aşağıdaki demo bunu mükemmel yapıyor. plunker içindeki kod İşte

geçerli:

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} }) 
    } 
} 

bu hata benim durumumda atılır neden kimse anlar mı?

Bu hatayı a plunker içinde yeniden üretmek istedim, ancak ne yazık ki herhangi bir istisna oluşturmuyor, uygulamanızla plunker arasında gördüğüm tek fark attribute değişkenidir. Uygulamamda bir model ve bir JSON nesnesi değil, bir şeyi değiştirebilir mi?

+0

Plunker örneği çalışır geciktirme bu nedenle tekrarlanabilir olmalıdır. AFAIR, bir olayın kaldırıldıktan sonra veya bir süre sonra işlenmesini sağlayan bileşenlerle ilgilidir. –

+0

Gerçekten, dizinde beta 8 yüklese bile beta 0'ı bildiren README.md dosyasına baktım. Ayrıca, github sorunundan da anladım, ama neden benim durumumda olduğunu anlayamıyorum. – Sunder

+0

Benioku henüz modası geçmiş. –

cevap

1

beta.8` `ile (ı yeniden olamaz çünkü değil test) biraz geçici mümkün olabilir Bu kodu

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

'da dinamik olarak oluşturulan girdilerle olay bağlamasının ilişkili olduğunu sanıyorum. Bu satırın etrafında 1ms'lik bir setTimeOut öğesi (0 işe yaramadı) this.strings = [] 'hatası kaldırıldı, teşekkür ederim. 1ms'lik bu kodun geciktirilmesinin neden bir olayın kaldırılan bir bileşenden kovulmasını önleyeceğini açıklayabilir misiniz? – Sunder

+1

Köşede değişiklik yapan bazı şeyler vardır; Açısal ise hala önceki değişikliği işliyor. 'setTimeout' sadece işlerin işlendiği sırayı değiştirir. Açısal, bu parçaları tamamlayabilir ve bu kod, daha sonra Angular tekrar kararlı bir durumda olduğunda gerçekleştirilir. Sorun, Açısal olarak sabitlendiğinde, içeriğin beklenen sıraya göre yürütülmediğine dikkat etmelidir. –

İlgili konular