İlk olarak, bu istisnanın yalnızca uygulamanızı dev modunda çalıştırdığınızda atılacağını unutmayın (beta-0'dan itibaren varsayılan olarak durum budur): enableProdMode()Uygulamayı önyüklerken çağrı yaparsanız , atılmaz ( bkz. güncellenmiş paket ).
İkincisi, bunu yapmayın, çünkü bu istisna iyi bir nedenle atılmaktadır: Kısacası, dev modundayken, her değişiklik algılamasının hemen ardından, ilkin sonundan bu yana hiçbir bağlantının değişmediğini doğrulayan ikinci bir tur gelir, Bu, değişikliklerin değişiklik algılamasının kendisinden kaynaklandığını gösterir.
Gövdenizde, bağlama {{message}}, ilk değişiklik algılama dönüşünün bir parçası olarak gerçekleşen kancada setMessage()gerçekleşen çağrınızla ngAfterViewInitdeğiştirilir. Bu kendi başına sorunlu değildir - sorun, setMessage()bağlamayı değiştirmesi, ancak yeni bir değişiklik algılama turunu tetiklememesidir; bu, gelecekteki bir değişiklik saptama turu başka bir yerde tetiklenene kadar bu değişikliğin algılanmayacağı anlamına gelir.
Paket servisi olan şey : Bağlamayı değiştiren her şeyin, bir değişiklik algılaması gerçekleştirdiğinde tetiklenmesi gerekir.
Bunun nasıl bir örnek için tüm isteklerine yanıt olarak Güncelleme Tycho çözüm eserleri @ gibi içinde üç yöntem yapın: cevabın @MarkRajcok dikkat çekti. Ama açıkçası, hepsi bana çirkin ve yanlış geliyor, tıpkı ng1'de alıştığımız bir tür hack gibi.
Vardır, Emin olmak için ara sıra bir tercihten başka bir şeye bunları kullanıyorsanız bu kesmek uygun koşullar ancak çok ara sıra esasına, bu tam olarak reaktif doğasını kucaklayan yerine çerçeveyi kavga etmen bir işarettir.
IMHO, daha deyimsel, "Angular2 yol" yaklaşan bu çizgisinde bir şeydir: ( plunk )
@Component({
selector: 'my-app',
template: `<div>I'm {{message | async}} </div>`
})
export class App {
message:Subject<string> = new BehaviorSubject('loading :(');
ngAfterViewInit() {
this.message.next('all done loading :)')
}
}
ExpressionChangedAfterItHasBeenCheckedErrormakalede davranışı ayrıntılı olarak açıklamaktadır.