![](/img/trans.png)
[英]setTimeOut() gets repeated in Angular Lifecycle Hooks: ngDoCheck, ngAfterContentChecked, ngAfterViewChecked
[英]Debounce Angular ngDoCheck lifecycle hook
我一直在進行一些有關在Angular組件中處理狀態的實驗。
假設我有一個計算成本很高的變量,它取決於其他幾個變量。 我可以編寫一個函數updateVar()
,並在我知道可能會影響它的每個事件上調用它。 通過訂閱。 但是,在5個以上的不同位置調用上述函數時,它不會感到很干燥,也不會很健壯。
因此,反跳DoCheck
Angular生命周期掛鈎怎么樣呢?
docheckSubject: Subject<any> = new Subject();
debounced: boolean = false;
constructor(private cd: ChangeDetectorRef) {}
ngOnInit() {
this.docheckSubject.debounceTime(50).subscribe(
() => this.ngDoCheckDebounced()
);
}
ngDoCheck() {
if (!this.debounced) {
this.docheckSubject.next();
} else {
this.debounced = false;
}
}
ngDoCheckDebounced() {
this.debounced = true;
this.updateVar();
this.cd.detectChanges(); // needed to reflect update in DOM
}
這是一個小例子 。
這種方法在我的真實應用中似乎可以正常工作,當然,更多的ngDoCheck()正在發生,並且量角器測試也不會抱怨。 但是我無法擺脫做一個骯臟,不太聰明的黑客的感覺。
問 :這會咬我嗎? 實際上,我是否完全需要它?
ngDoCheck
經常被調用:
https://angular.io/guide/lifecycle-hooks#docheck
This hook is called with enormous frequency—after every change detection cycle no matter where the change occurred.
將此鈎子用於除Angular不知道的變量之外的其他任何東西,以尋找更改檢測是一個壞主意。 (例如,輸入對象更改其屬性之一的值)。 防彈跳有一定幫助,但是您仍然非常頻繁地執行該邏輯,並且在不再需要它時(例如,當debounced == false
)將繼續這樣做。
我認為您的解決方案可以使用,但是我認為這種方法的開銷比其他方法差得多。 可能有必要將更新邏輯作為Observable
鏈的一部分,或者將Observables
傳遞到將這種邏輯添加到鏈中的函數中。
經過幾個月沒有問題的生產(AFAICT),我最終刪除了它,因為它最終導致e2e(量角器)測試受阻,直到有人手動單擊頁面。 顯然是不可持續的。
我無法正確診斷此問題的原因,它可能是源於我們代碼中無關部分的怪異現象,但是比后悔更安全。
您能否將變量放入getter中,並且僅在檢索到變量時重新計算?
這是一個簡單的示例:
//our root app component
import {Component, NgModule, VERSION} from '@angular/core'
import {BrowserModule} from '@angular/platform-browser'
@Component({
selector: 'my-app',
template: `
<div>
<h2>Hello {{name}}</h2>
<div>x={{x}}</div>
<div>y={{y}}</div>
<button (click)="increment()">Increment</button>
<div>Calculated Value={{calculatedValue}}</div>
</div>
`,
})
export class App {
name:string;
x: number = 0;
y: number = 10;
get calculatedValue(): number {
return this.x * this.y;
}
constructor() {
this.name = `Angular! v${VERSION.full}`
}
increment(): number {
this.x++;
}
}
以及相關的Plunker: https ://plnkr.co/edit/QC7mkbsbjRRBjJOjWSHe ? p = preview
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.