- 什麼是區域?
- 角度ngZone與zone.js有什麼不同?
- 什麼時候應該使用它們?有人可以幫助使用ngZone的實際例子嗎?
我已經通過角度文件在這裏然而,我無法得到完整的理解。角度區域
https://angular.io/api/core/NgZone
我已經通過角度文件在這裏然而,我無法得到完整的理解。角度區域
https://angular.io/api/core/NgZone
NgZone
是圍繞Zone.js的包裝是,爲了使他們可追蹤圍繞創建異步函數上下文庫。
Angular的變化檢測主要依賴於Zones
,How?
當需要運行變更檢測時,角度需要一種不受影響的方式,它基本上只是更新DOM
以表示最新的模型(javascript)更改。
試想一下,我們有波紋管例如:
<div id="content"></div>
我們的JavaScript代碼
在某處我們有
const element = document.getElementById('content');
function updateText(){
element.innerHtml = myText+ ": updated at time"+Date.now()
}
比方說,最初我打算更新content
一個招呼:
const myText = "Hello";
this.updateText();
這會將我的html內容更新爲文本:「Hello updated at時間19:30"
,然後讓說,我想更新myText
變量是用戶點擊後,別的東西:
<button onClick="updateTheTextAgain()"></button>
updateTheTextAgain(){
this.myText = "Hi there";
}
如果我點擊該按鈕有什麼會發生?
Nothing;
嗯,其實,這不是什麼都沒有,我設法更新變量,但我沒有更新的觀點(我沒有發現模型的變化),所以我需要調整我updateTheTextAgain
是:
updateTheTextAgain(){
this.myText = "Hi there";
this.updateText(); /// Making sure I'm detecting the change (I'm updating the `DOM`)
}
現在,單擊按鈕將更新我的視圖(因爲手動更改檢測)。
這顯然不是最好的主意,因爲那時我必須編寫很多updateText
函數,並且在更新模型後,我希望視圖被更新的任何地方調用它們,right(回到Angular1並記住$scope.apply()
)?
這裏是ZoneJs
是驚人的。
成像,如果我能改寫onClick
功能,我指的是瀏覽器的原始的onClick函數爲:
const originalOnClick = window.onClick;
window.onClick = function(){
originalOnClick();
this. updateText();
}
這就是所謂的monkey patching
或本機功能open heart surgery
。
我該怎麼辦?
後,我把我的patched onClick
頁面,所有的onClick
功能會在整個應用程序被寫入,要經過我patched onClick
,這意味着,我不必再後運行updateText()
功能每一個onclick,因爲它支持到click
甚至處理程序本身。
在Angular中,updateText
是change detection
,Angular已經掛鉤了所有本地事件(通過使用區域)。
所以,當你寫:
setTimeout(()=>{
console.log('Do something');
},100);
你實際上寫是一樣的東西:
setTimeout(()=>{
console.log('Do something');
runAngularsChangeDetection();
},100);
以上是遠是什麼在現實中發生的事情,但它的整體的心臟我們爲什麼需要它們/
更新:
我們什麼時候應該使用NgZone
。
會有很多的情況下,當你想使用NgZone
,我可以說出兩種:
1 - 當你想要的東西角的變化檢測之外運行:
還記得我說過角有掛鉤在所有的異步事件? window.onScroll
就是其中之一,現在可以說,我們想做一些當用戶滾動計算,你通常做的是:
window.onscroll =()=>{
// do some heavy calculation :
}
現在,滾動時,你函數被調用,通常你所期望的,但你可能會注意到你會遇到一些性能問題,這可能是因爲Angular在每一個滾動事件(預期行爲)上運行changeDetection
。
如果你的組件中有很多綁定,那麼你一定會注意到滾動時的性能下降。
所以一個方法是說,哎角,無視我的onscroll
事件,我知道我在做什麼,我不想讓你運行變化檢測,在這種情況下,你會使用NgZone
constructor(private zone:NgZone){
this.zone.runOutsideOfAngular(()=>{
window.onscroll =()=>{
// do some heavy calculation :
}
})
}
這將確保Angular不會在滾動時運行更改檢測。
另一種情況是與上面完全相反,你有一個函數在Angular的區域之外,你希望它在裏面,就像第三方庫爲你做一些東西,你想要它綁定到你的角度週期。
this.zone.run(()=>{
$.get('someUrl').then(()=>{
this.myViewVariable = "updated";
})
});
不使用區,你最有可能需要做的:
$.get('someUrl').then(()=>{
this.myViewVariable = "updated";
this.changeDetectorRef.detectChanges();
})
但是請注意,當你的功能區(run方法)中您不必手動調用detectChanges
你自己和角會做這項工作
目前官方文件是不是達到標準。有人在Angular中做瘋狂的東西,所以Pascal Precht。他的下面的文章將幫助你瞭解什麼是Zone
和ngZone
。
https://blog.thoughtram.io/angular/2016/02/01/zones-in-angular-2.html
感謝您對問題1和問題2的詳細解釋。什麼時候應該在角項目中使用ngZone。如果我們這樣做:從'@ angular/core'導入{NgZone};我們可以使用API,比如run,runOutsideAngular等,我想知道他們什麼時候應該在實踐中使用? –
我會更新我的答案 – Milad
這是否回答你的問題? – Milad