Angular 角域 什么是区域 ngZone与zone.js有何不同 什么时候使用?有人能提供使用ngZone的实例吗
我在这里查阅了一些有角度的文档,但是我不能完全理解Angular 角域 什么是区域 ngZone与zone.js有何不同 什么时候使用?有人能提供使用ngZone的实例吗,angular,zone.js,Angular,Zone.js,我在这里查阅了一些有角度的文档,但是我不能完全理解 当前的官方文件不符合标准。有些人会做一些疯狂的事情,而也是如此。他下面的文章将帮助您理解什么是Zone和ngZone NgZone是Zone.js的包装器,Zone.js是一个库,它围绕异步函数创建上下文,以使它们可跟踪 Angular的变化检测严重依赖于区域,如何检测 Angular需要一种理解何时运行更改检测的方法,这基本上就是更新DOM,以表示最新的模型(javascript)更改 假设我们有下面的例子: <div id="co
当前的官方文件不符合标准。有些人会做一些疯狂的事情,而也是如此。他下面的文章将帮助您理解什么是
Zone
和ngZone
NgZone
是Zone.js的包装器,Zone.js是一个库,它围绕异步函数创建上下文,以使它们可跟踪
Angular的变化检测严重依赖于区域
,如何检测
Angular需要一种理解何时运行更改检测的方法,这基本上就是更新DOM
,以表示最新的模型(javascript)更改
假设我们有下面的例子:
<div id="content"></div>
假设一开始我将用hello更新内容
:
const myText = "Hello";
this.updateText();
这会将我的HTML内容更新为文本:“Hello在19:30更新”
然后假设我想在用户单击后将myText
变量更新为其他变量:
<button onClick="updateTheTextAgain()"></button>
updateTheTextAgain(){
this.myText = "Hi there";
}
现在,单击按钮将更新我的视图(因为手动更改检测)
这显然不是最好的主意,因为我必须编写大量的updateText
函数,并在更新模型后在任何我想更新视图的地方调用它们,对吗(回到Angular1并记住$scope.apply()
)
这里是ZoneJs
令人惊奇的地方
想象一下,如果我可以重写onClick
函数,我的意思是浏览器的原始onClick函数是:
const originalOnClick = window.onClick;
window.onClick = function(){
originalOnClick();
this. updateText();
}
这被称为本机功能的猴子修补术
或心脏直视手术
我能从中得到什么
在我将我的patched onClick
放入页面后,整个应用程序中要编写的所有onClick
函数都将通过我的patched onClick
,这意味着,每次onClick之后,我不必再运行updateText()
函数,因为它被烘焙到click
事件处理程序本身中
在Angular中,updateText
是更改检测
,Angular在所有本机事件中都有挂钩(通过使用区域)
所以当你写作时:
setTimeout(()=>{
console.log('Do something');
},100);
你实际上写的是这样的:
setTimeout(()=>{
console.log('Do something');
runAngularsChangeDetection();
},100);
上述内容与现实情况相去甚远,但它是整个变化检测和区域的核心,我们为什么需要它们/
**更新:**
我们什么时候应该使用NgZone
当您想使用NgZone
时,会有很多情况,我可以列举两种:
1-当您希望某些内容超出Angular的更改检测范围时:
记得我说过Angular在所有异步事件中都有钩子吗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的区域之外,你希望它在内部,就像第三方库为你做一些事情,你希望它绑定到你的Angular循环
this.zone.run(()=>{
$.get('someUrl').then(()=>{
this.myViewVariable = "updated";
})
});
如果不使用Zone,您很可能需要执行以下操作:
$.get('someUrl').then(()=>{
this.myViewVariable = "updated";
this.changeDetectorRef.detectChanges();
})
但是请注意,当您的函数位于区域(run方法)内时,您不必自己手动调用detectChanges
,angular将完成此工作感谢您对问题1和2的详细解释。ngZone何时应用于角度项目。如果我们这样做:从'@angular/core'导入{NgZone};我们可以使用诸如run、runOutsideAngular之类的API,所以,我想知道在实践中应该何时使用它们?嗨@Milad我如何从windows对象访问ngzone?有可能吗?@DariuszFilipiak一切皆有可能,但你为什么要这样?你可能想在Angular的变化检测中运行一些东西,对吗?如果这是最好的答案,那是个坏主意!谢谢
this.zone.run(()=>{
$.get('someUrl').then(()=>{
this.myViewVariable = "updated";
})
});
$.get('someUrl').then(()=>{
this.myViewVariable = "updated";
this.changeDetectorRef.detectChanges();
})