我在这里经历了角度文档,然而,我无法完全理解。
答案 0 :(得分:19)
NgZone
是Zone.js的包装器,它是一个库,它创建一个围绕异步函数的上下文,以使它们可跟踪。
Angular的变化检测严重依赖于Zones
,如何?
Angular需要一种了解何时运行变更检测的方法,这基本上只是更新DOM
以代表最新模型(javascript)更改。
想象一下,我们有一个例子:
<div id="content"></div>
在我们的javascript代码中,我们有
const element = document.getElementById('content');
function updateText(){
element.innerHtml = myText+ ": updated at time"+Date.now()
}
让我们说最初我要用hello更新content
:
const myText = "Hello";
this.updateText();
这会将我的HTML内容更新为文本:“Hello在19:30更新”
然后假设我想在用户点击后将myText
变量更新为其他内容:
<button onClick="updateTheTextAgain()"></button>
updateTheTextAgain(){
this.myText = "Hi there";
}
如果点击该按钮会发生什么?
<强> 没有 强>
嗯,实际上,它不是,“没什么”,我设法更新变量,但我没有更新视图(我没有检测到模型的变化),所以我需要调整我的{{1成为:
updateTheTextAgain
现在,单击该按钮将更新我的视图(因为手动更改检测)。
这显然不是最好的主意,因为那时我必须编写很多 updateTheTextAgain(){
this.myText = "Hi there";
this.updateText(); /// Making sure I'm detecting the change ( I'm updating the `DOM`)
}
函数,并在我更新模型之后将其调用到任何我希望更新的地方(右边)(返回Angular1并记住updateText
)?
这里$scope.apply()
令人惊叹。
想象一下,如果我可以重写ZoneJs
函数,我的意思是浏览器的原始onClick函数:
onClick
这称为本地函数的 const originalOnClick = window.onClick;
window.onClick = function(){
originalOnClick();
this. updateText();
}
或monkey patching
。
我到底得到了什么?
在我将open heart surgery
放入页面后,将要在整个应用程序中编写的所有patched onClick
函数将通过我的onClick
,这意味着,每次onclick后我都不必再运行patched onClick
函数了,因为它已经被updateText()
事件处理程序本身所包含。
在Angular中,click
是updateText
,Angular在所有本机事件中都有钩子(通过使用区域)。
所以当你写:
change detection
你实际上写的是:
setTimeout(()=>{
console.log('Do something');
},100);
上面是远离现实中发生的事情,但它是整个变化检测故事的核心, setTimeout(()=>{
console.log('Do something');
runAngularsChangeDetection();
},100);
我们为什么需要它们/
**更新:**
我们应该何时使用Zones
。
当您想要使用NgZone
时会有很多情况,我可以说出两个:
1-当你想要在Angular的变化检测之外运行时:
还记得我说Angular在所有异步事件中都有钩子吗? NgZone
就是其中之一,现在假设我们想在用户滚动时进行一些计算,你通常做的是:
window.onScroll
现在,滚动时,正常按照您的预期调用函数,但您可能会注意到性能问题,这可能是因为Angular在每个滚动条上运行 window.onscroll = ()=>{
// do some heavy calculation :
}
事件(预期行为)。
如果您的组件中有很多绑定,那么您肯定会注意到滚动中的性能下降。
所以一种方法就是说,嘿Angular,忽略我的changeDetection
事件,我知道我在做什么,我不希望你运行变更检测,在这种情况下,你会使用{ {1}}
onscroll
这将确保Angular不会在滚动时运行更改检测。
另一个案例与上面完全相反,你有一个以某种方式在Angular区域之外的函数,你希望它在里面,就像当第三方库为你做一些东西而你想要它受到你的角度循环的束缚。
NgZone
不使用Zone,您很可能需要这样做:
constructor(private zone:NgZone){
this.zone.runOutsideOfAngular(()=>{
window.onscroll = ()=>{
// do some heavy calculation :
}
})
}
但请注意,当您的功能位于区域内(运行方法)时,您不必亲自手动调用 this.zone.run(()=>{
$.get('someUrl').then(()=>{
this.myViewVariable = "updated";
})
});
,而角度将执行此任务
答案 1 :(得分:1)
目前的官方文件未达标。有些人在Angular中做过疯狂的事情, Pascal Precht 也是如此。他的下文将帮助您了解Zone
和ngZone
。
<强> https://blog.thoughtram.io/angular/2016/02/01/zones-in-angular-2.html 强>