2016-07-23 49 views
3

後從RC1升級後的表達改變RC4我得到以下異常:angularjs 2 RC4變化檢測:在檢出

 
Expression has changed after it was checked. Previous value: 'false'. Current value: 'true' 

在線研究此問題後,讀我所能,我還是別後不知道如何以「有角度」的方式糾正這個問題(沒有超時等)。

我明白當開發模式變化檢測運行一次,只是爲了確保一切都沒有改變。我也明白,任何改變綁定的東西都會引發新一輪的變化檢測。

什麼,我不明白的是爲什麼新一輪檢測的事件發生時不會自動觸發和如何糾正。

我有一個非常簡單的用例。最上面的組件負責顯示外部UI。它還包含應該隱藏/顯示的控件。此行爲由活動路由組件控制。

子實例化由活動路由(router-outlet)發生,而不是手動發生。

因此,這個最上面的組件和所有子組件都訂閱共享服務內的均衡器併發送事件。

最上面的組件還訂閱了Oninit上的此事件。當它收到事件時,它會更改一個局部變量。這反映在這個組件的html上。

AppComponent

export class AppComponent implements OnInit { 
    hidePageControls:boolean = true; 

    constructor(private apiService: ApiService) {} 

    ngOnInit(): any { 
    let me = this; 

    this.apiService.hidePageControls.subscribe(value => me.hidePageControls = value); 
    } 
} 

ChildComponent

ngOnInit() { 
    me.apiService.hidePageControls.emit(false); 
} 

這樣做的理由是,當用戶導航到該應用程序的不同部分,使用不同的組件。這些組件然後將事件發送到最頂層組件以顯示/隱藏特定控件。

我已經閱讀過可能的解決方案,包括setTimeout(),直接調用變化檢測等。人們也說我們不應該'打架',我同意這個框架。

所以,請讓我知道如果我的孩子組件通知父組件的想法是角度思考的「錯誤」方式,並且通過任何方式讓我知道這樣做的「角度」方式會是什麼樣子喜歡。


編輯

唯一的解決辦法我發現對於這種類型的錯誤是使用超時這樣:

拆離變化檢測器。 手動觸發事件觸發更改檢測輪。

constructor(private apiService: ApiService, private categoryService: CategoryService, private router: Router, private cd: ChangeDetectorRef) { 
    this.cd.detach(); 
} 

. 
. 
. 
. 

this.apiService.hidePageControls.subscribe(value => { 
    me.hidePageControls = value; 
    setInterval(() => { 
     me.cd.detectChanges(); 
    }, 100); 
}); 

按我的理解,這將額外的發展變化檢測運行已因超時結束後引起變化檢測圓。我覺得這是一個挑剔的解決方案。

請讓我知道,如果有更好的存在。

+0

對這個問題有什麼消息?你有沒有找到另一種方式來處理它或另一種方式來建立你的服務/組件?謝謝! – vinagreti

+0

我還沒有找到任何'角度'做這種事情的方式。如上所述,我選擇了手動更改檢測和超時。我將等待第一個版本再次研究。 – sm0ke21

回答

1

我使用幾乎相似的方式來啓用/禁用控制取決於子元素的決定。 在角度更新(rc1-> rc4)之前,它像一個魅力一樣工作。更新之後,組件在第一次加載時開始中斷。 斷裂的變化是:

門面:變化EventEmitter到默認(#8761)被同步(e5904f4)

link to issue

父組件值的變化及其變化的檢測回合完成後在子組件的初始化期間。


修復您的問題可能是:

// in apiService 
hidePageControls = new EventEmitter(true); 

真正在EventEmitter構造函數將迫使它是異步

希望能對大家有所幫助。

+0

hidePageControls = new EventEmitter (true);如果你需要鍵入它 – Goris

+0

這個爲構造函數提供值的方法似乎在rc4上適用於我 – sm0ke21

0

角度不喜歡何時更改檢測導致模型更改。

ngOnInit()被變更檢測調用。

您可以使用setTimeout()來延遲更改,直到更改檢測完成。 setTimeout()會導致應用程序範圍內的更改檢測運行,因此無法提供建議。

您可以使用另一個生命週期回調不是由變化檢測

稱爲

至於我記得ngAfterViewInit作品對於這種情況。

ngAfterViewInit() { 
    me.apiService.hidePageControls.emit(false); 
} 

另一種方式是注入ChangeDetectorRef,並呼籲改變檢測明確,使角意識到變化的,它拋出之前:

constructor(cdRef: ChangeDetectorRef) {} 

ngOnInit() { 
    me.apiService.hidePageControls.emit(false); 
    this.cdRef.detectChanges(); 
}